It's hard to give specifics as the form is very complex. I do have a general example of a pattern prevalent throughout the form. The pseudo code goes something like this:
// Page class MyPage extends Page { onInitialize() { Panel p = PanelFactory.createPanel("myPanel", "myObject"); this.add(p); } } // Factory for creating panels that use a document cache based loadable detachable // model class PanelFactory { Panel createPanel(String panelName, String cachedObjectName) { // uses the document name to retrieve doc from the cache using it's name DocumentCacheLDM ldm = new DocumentCacheLDM(cachedObjectName); // return a panel initialized with the model if ("myPanel".equals(panelName)) { return new MyPanel(ldm); } .... } } // Panel class MyPanel extends Panel { MyPanel(final IModel cacheLDM) { // create an LDM that uses the cache LDM and an expression. Note that it is marked final // so it can be used in the list panel below final LoadableDetachableModel abc = new LoadableDetachableExpressionModel(cacheLDM, "a.b.c"); // another one based on abc LoadableDetachableModel def = new LoadableDetachableExpressionModel(abc, "d.e.f"); // create a panel for DEF object Panel subPanel = new SubPanel(def); this.add(subPanel); // create a model for a repeating list of GHI LoadableDetachableModel ghi = new LoadableDetachableExpressionModel(abc, "g.h.i"); // create a repeating section for GHIs ListPanel<GHI> listPanel = new ListPanel<GHI>("listPanel", ghi) { @Override public Component createItemComponent(String id, IModel<GHI> model, Item item) { return new GHIPanel(id, model, isReadonly, mode); } @Override public void addItem(AjaxRequestTarget target) { // uses abc model from above to add the new GHI abc.getObject().addNewGHI(); } @Override public IModel<GHI> getItemModel(GHI item) { // create an LDM for the GHI item that might use the items's id internally // to load return new LoadableDetachableExpressionModel(abc, item); } @Override public void removeItem(GHI item, AjaxRequestTarget target) { abc.getObject().deleteGHI(item); } } this.add(listPanel); } } This pattern, in our case, seems to end with a bunch of models that never get detached. Therefore on subsequent request we end up with some parts of the form reattached to the document from the cache and other parts attached to orphaned transient models from their unattached models. Then when you submit the form the components that are attached to the cached object update the correct model object but the ones that didn't get detached properly update the orphaned model objects. So we end up with data lose. To get this working we changed the MyPanel class to something like this: // Panel class MyPanel extends Panel { private LoadableDetachableModel abc; private LoadableDetachableModel def; private LoadableDetachableModel ghi; void onDetach() { abc.detach(); def.detach(); ghi.detach(); } MyPanel(final IModel cacheLDM) { // create an LDM that uses the cache LDM and an expression abc = new LoadableDetachableExpressionModel(cacheLDM, "a.b.c"); // another one based on abc def = new LoadableDetachableExpressionModel(abc, "d.e.f"); // create a panel for DEF object Panel subPanel = new SubPanel(def); this.add(subPanel); // create a model for a repeating list of GHI ghi = new LoadableDetachableExpressionModel(abc, "g.h.i"); // create a repeating section for GHIs ListPanel<GHI> listPanel = new ListPanel<GHI>("listPanel", ghi) { @Override public Component createItemComponent(String id, IModel<GHI> model, Item item) { return new GHIPanel(id, model, isReadonly, mode); } @Override public void addItem(AjaxRequestTarget target) { // uses abc model from above to add the new GHI abc.getObject().addNewGHI(); } @Override public IModel<GHI> getItemModel(GHI item) { // create an LDM for the GHI item that might use the items's id internally // to load return new LoadableDetachableExpressionModel(abc, item); } @Override public void removeItem(GHI item, AjaxRequestTarget target) { abc.getObject().deleteGHI(item); } } this.add(listPanel); } } After instrumenting LoadableDetachableModel and RequestCycle to track all the LDMs, we can now see that after the detach process executes at the end of the request cycle all of the models are detached and the problems appear to go away. Does this solution make sense? Is there something fundamentally wrong with the pattern? Is it because we don't set a model on MyPanel thereby breaking the detach process somehow? Is the use of the final "abc" model in the list panel anonymous inner type causing inadvertent serialization problems? We are using Wicket 6 and the problem doesn't become prevalent until the form has been mildly stressed. Presumably this is because we have reached some threshold that starts to trigger some Wicket serialization behaviour. Any insights would be helpful to help us get to the root cause. Thanks -- View this message in context: http://apache-wicket.1842946.n4.nabble.com/Wicket-model-problem-tp4673620p4673662.html Sent from the Users forum mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org