Hi all,

Our Wicket 1.4 project (currently 1.4.3) uses tabs on some pages to display
linked information. For example, an Account may have a User. On the Account
page, there would be a User tab in this case.  The User is a PropertyModel
on a LoadableDetachableModel for the Account (which grabs from the DB).

We notice that whenever one tab accesses any part of the model in its
constructor, we get two queries to the database to display the page. Some
digging revealed the cause:

Tabbed panel does the following (simplified).

1. Instantiate the new Panel being switched to (which causes the
LoadableDetachableModel to load() as the constructor uses it)
2. call addOrReplace with this new Panel. This causes the old Panel to be
removed and detach() to be called on it. Unfortunately, the other tab also
had a PropertyModel on the same Account object. This means that the
LoadableDetachableModel that's already queried the db within this request
will detach()

Later, the rendering causes the LoadableDetachableModel to load() again.

It could be argued that we shouldn't be accessing the model directly in the
constructor but instead setting PropertyModels on its attributes to be
displayed at render time. I have managed to fix almost all of our pages to
do this*, but the problem is how fragile this is. It's difficult to write a
test case that verifies that no page needlessly causes two loads() in any
LodableDetachableModel, and the consequence of such a mistake would be no
less than doubling the load on the database.

I suggest that TabbedPanel should instead remove any old tab before
instantiating the new tab so models won't be unexpectedly detached before
rendering even happens.  I would be willing to supply a JIRA and patch
unless somebody out there a knows better way to do all of this :)

Thanks,
Neil

* My main obstacle has been PageParameters links which don't seem to be able
to take a Model as an argument. Is there a way to work around this?

Reply via email to