Wicket Anti-Patterns: Avoiding Session Bloat
Wicket is a wonderful framework for building complex web applications. However, it is all too easy to hang your self with session use in Wicket. Wicket manages the session on your behalf so you don’t have to worry about UI state. Since every page is serialized to the session, you need to be extra careful with your entity graph so it does not get serialized with the page. Here are some anti patterns that I have personally stumbled upon.
Anti-Pattern #1.
super(id,userMdl);
final User user = getModelObject();
IModel<List<User>> model = new LoadableDetachableModel<List<User>>() {
private static final long serialVersionUID = 1L;
@Override
protected List<User> load() {
// A Stale User entity is now serialized with each page view
// This can consume lots of session space if the user entity is large.
return getWebSession().getUserService().getUserFriends(user);
}
};
}
Here is the correct way to do this
public FooPanel(String id,IModel<User> userMdl) {
super(id,userMdl);
final User user = getModelObject();
IModel<List<User>> model = new LoadableDetachableModel<List<User>>() {
private static final long serialVersionUID = 1L;
@Override
protected List<User> load() {
User u = FooPanel.this.getModelObject();
return getWebSession().getUserService().getUserFriends(u);
}
};
}
The entity is fetched each page view, and NOT serialized with the page. The only thing that gets serialized is the fetching model.
Anti-Pattern #2.
Here is the correct way to do this
The PropertyModel holds a reference to the Model which fetches the User on each page view. That way the User object is always fresh and is not serialized with the page.
Anti-Pattern #3.
// The stale User object will be in your session
// for the life span of the stateful page.
super(id.new Model(user));
}
Here is the correct way to do this, though not very elegant.
super(id);
final int id = user.getId();
setModel(new LoadableDetachableModel<List<User>>() {
@Override
protected List<User> load() {
return getUserDao().findById(id);
}
});
I hope these Wicket anti-patterns help you avoid the common pitfalls I have run into while developing
Fabulously40


Nice post!
I have a question about #1.
- Do you really need both using LoadableDetachable AND
User u = FooPanel.this.getModelObject();
Why adding this last line if the IModel if Detachable?
@gabriel
User u = FooPanel.this.getModelObject(); is referencing the passed userMdl. You don’t want to use the user object in the inner class directly or it fully gets serialized. This way only the lightweight userMdl gets serialized.
Wicket is full of surprises when it comes to session bloat if your not careful.
Nice post, however there is a problem in the layout of the article: the anti pattern #3 appears in the middle of a code box.