i already built something similar to the page.getreference() Matej is talking about. see PageId, Page#getPageId(), and RequestCycle#urlFor(PageId). this is very useful for building breadcrumbs as you dont have to pass a stack of pages around.
generally i agree, supporting page references is a pita. whether or not it should be considered a bad practice i dont claim to know, but it is definitely causing as headaches. i would remove the specialized serialization code, and if we can detect a page reference from one page to another during serialization i would log a warning. -igor On Mon, Mar 2, 2009 at 2:38 PM, Matej Knopp <[email protected]> wrote: > Hi, > > more perceptive people have probably noticed that there is some really > obscure page serialization related code in Wicket. What it is supposed > to do is to make sure that when PageA holds reference to pageB, pageA > and pageB get serialized separately and when pageA is deserialized, > pageB is loaded also separately. So that the two pages would not be > serialized in one piece. > > Unfortunately this is not as simple as it sounds, because pageB can > hold reference to pageC which in turn can have an object that is > anonymous class from pageA, so we need to deal with circular > references, implicit references and lot of other nasty things. The > bottom line is, this causes many weird serialization related bugs that > are extremely difficult to fix. The code is also big pain to maintain. > > Simply put, passing references between pages and page serialization > don't mix nicely. We need page serialization because it really helps > scalability and memory consumption so I think it might be time to > "deprecate" page references. > > Of course there would be a simple alternative. > > I.e. instead of > > class PageA ... > { > ... > public void doSomething() { > setResponsePage(new PageB(this)); > } > } > > it would be > > class PageA ... > { > ... > public void doSomething() { > setResponsePage(new PageB(this.getReference())); > } > } > > and > > class PageB ... > { > public PageB(final PageReference<PageA> pageA) > { > // to get the actual instance if you need it > PageA a = pageA.get(); > > // or use the reference directly > add(new PageLink("back", pageA); > > // or even like this > add(new Link("back2") { public void onClick() { > getRequestCycle().setResponsePage(pageA) } }); > } > } > > Also this would help the performance, because if PageB only uses pageA > to return back (which is IMHO the most common case) it would only > require tiny PageReference object instead of entire page. > > -Matej >
