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 <matej.kn...@gmail.com> 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
>

Reply via email to