myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Francisco Passos" <francisco.pas...@gmail.com>
Subject Re: [Tomahawk] t:saveState - one step further
Date Mon, 25 Jun 2007 22:24:56 GMT
Hello once again!

jsf-comp solved my problems beautifully.

So, as promised, for those who may be struggling with a 3-step solution to
keep request-scoped bean state between subsequent requests, without
repeating initialization (thus avoiding several unnecessary hits to a
database, for instance):

1. find a way to carry the bean state from one request to the next: use
Tomahawk's t:saveState [1], it's what it does and very well, provided your
bean is serializable or implements a particular interface

2. equip your bean with the way to know if it is already initialized or not
(to avoid repeating the same work)

    private boolean initialized = false;

    public final void initialize() {
        if (!initialized) {
            // do your initialization here
            initialized = true;
        }
    }

You might consider creating an abstract bean class so many of your beans can
inherit this behaviour, as I have.

3. find a way to call initialize everytime you enter a page that requires
it:

I used jsf-comp [2] (actually a particular subproject named jsfExt which
contains only the specific component necessary for this), which contains a
mechanism for providing "on-load" functionality; simply put, it's a
PhaseListener and an XML file that indicates which bean methods (via EL
expressions) should be executed before the RENDER_PHASE. It's simple as hell
and that's why I love.

An example can explain it a lot better than just talking about it:

on the onload-config.xml (the configuration file for jsf-comp OnLoad
component):

<navigation-rule>
    <view-id>/pages/ficha/myPage.xhtml</view-id>
    <action>#{myBean.initialize}</action>
</navigation-rule>

Having this ensures that everytime you access that particular view the
initialize method in myBean is called. That, in turn, ensures that either
the bean is already initialized (and won't be reinitialized, thus preventing
further database hits / heavy computation / etc.), or the bean is not yet
initialized and will then be, right before the page is presented. Of course,
this only works because Tomahawk's t:saveState has previously restored the
bean to a state where it contains the values previously obtained during
initialization, alongside the private boolean flag to indicate it.

So there you go, a simple "egg-of-Columbus" solution for a problem that has
bugged me for a while.

I hope many find this description useful.

Finally, I need to thank a lot of you that put up with me for a while on
this issue, both from the Tomahawk and the Trinidad projects.

Regards,

Francisco Passos

[1] http://myfaces.apache.org/tomahawk/uiSaveState.html
[2] http://jsf-comp.sourceforge.net/components/onload/index.html

On 6/25/07, Francisco Passos <francisco.passos@gmail.com> wrote:
>
> Thank you for your suggestions.
>
> I'm going to look into the first two, since I understand Shale requires a
> tight coupling between page and bean naming conventions, which is not
> completely suitable for what I intend to do.
>
> I'm using Trinidad and Facelets. I hope to find no restrictions to the use
> of these libraries.
>
> If I get this to work successfully, I'll report it here, so others can
> benefit as well.
>
> Thank you,
> Francisco Passos
>
> On 6/25/07, Andrew Robinson <andrew.rw.robinson@gmail.com> wrote:
> >
> > Possibly use an on-load method for your page. The following libraries
> > provide this functionality:
> >
> > JBoss-Seam
> > jsf-comp on-load
> > Shale view handler
> >
> > -Andrew
> >
> > On 6/25/07, Francisco Passos < francisco.passos@gmail.com> wrote:
> > > Good afternoon.
> > >
> > > I've been trying for some time to figure a way to properly use
> > t:saveState.
> > >
> > > I've been able to easily use its core functionality of keeping state
> > between
> > > successive requests.
> > > However, for beans which are supposed to carry information from a
> > database
> > > to be presented on the screen, one must initialize its properties. And
> > thus
> > > I'd like to have a specific method on my beans which would be called
> > > whenever such initialization is needed. For now, I'm using the setter
> > of a
> > > managed-property on my bean - which is called everytime a new request
> > is
> > > processed for that bean.
> > >
> > > Now comes the tricky part: I want to avoid going to the database and
> > > retrieving the data I've already collected. So I use t:saveState for
> > that.
> > > And I've set a private boolean in the bean which is checked on the
> > > initialization method before going to the database once more... the
> > problem
> > > is, it seems to me, that when my init method runs, t:saveState's bean
> > > restoration process has not yet occurred and so the private boolean
> > that
> > > carries the information on whether the bean has already been
> > initialized is
> > > still set to false - so it goes to the database once more (and later
> > the
> > > restore takes place over the newly acquired data). As you can see I
> > need to
> > > switch the order of these two steps...
> > >
> > > So what I'm looking for is a standard (or non-standard) way of
> > invoking a
> > > method on my bean everytime a page uses that bean, but only after the
> > > t:saveState component has properly restored the bean. And obviously
> > the
> > > solution I'm looking for must also call this method for the first
> > access to
> > > the page, where there is no state for the component to restore.
> > >
> > > Is there already a solution for this?
> > >
> > > Thank you,
> > > Francisco Passos
> > >
> >
>
>

Mime
View raw message