aspose file tools*
The moose likes JSF and the fly likes Why are getters called multiple times? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "Why are getters called multiple times?" Watch "Why are getters called multiple times?" New topic
Author

Why are getters called multiple times?

Paolo Rodeo
Greenhorn

Joined: Dec 11, 2010
Posts: 18

Hi,

I noticed that when I have for instance a <h:selectOneListbox> on a (view scoped) page, the getter for the selectItems is usally called multiple times for each page refresh. Why is this? Looks like this is a common issue with many JSF components.

I'm not so happy with that, as this forces me to save the item map locally in the bean where the building of the map may be a costly operation. Storing the map locally in the bean moves the decision making of when the map is to be rebuilt from the page to the bean as well. This I don't like (and I think it's fundamentally wrong). On the page it's easy to decide, depending on the user actions, when to update the list and using ajax that's easy to implement. Now I have to copy all that knowledge to the bean as well.

Would like to hear some opinions on this. Am I doing something wrong, is this a fundamental JSF shortcoming, a sloppy JSF implementation, a problem with my installation, or what?

Any comments highly appreciated,
regards, Paul.
Mark Reyes
Ranch Hand

Joined: Jul 09, 2007
Posts: 426
Hi Paolo,

Here's my 2 cent.

I happen not to find the answer myself but I realized that no business logic should be added in a getter and setter of a managed bean. The getter and setter are there to act as a "glue" between your UI and the controller (or model).
I actually have a similar question to you, but I was wondering which getter would fire first and add business logic in there but in the end after some reading I realized what I mentioned above.


I'm not so happy with that, as this forces me to save the item map locally in the bean where the building of the map may be a costly operation. Storing the map locally in the bean moves the decision making of when the map is to be rebuilt from the page to the bean as well. This I don't like (and I think it's fundamentally wrong). On the page it's easy to decide, depending on the user actions, when to update the list and using ajax that's easy to implement. Now I have to copy all that knowledge to the bean as well.


Now, I am not sure regarding this. It seems that you are putting your business logic in the getter methods or I could be wrong.

The getters are called several times so you would often see lazy initialization in the net such as this.



In this case, no matter how many times the getter is called, the functional aspect is done only once.

Not sure if I did help you though as your question is vague for me..
Thanks.


Sean Clark ---> I love this place!!!
Me ------> I definitely love this place!!!
Paolo Rodeo
Greenhorn

Joined: Dec 11, 2010
Posts: 18

Hi Mark,

Thanks for your time and reply. Much appreciated. Let me try to make my point more clear using an example.

Take for instance the classic example with one selection list to select a country and another one to select a city within that country, with the getters and setters as follows:



In my page I would prefer to have something like:



Now the city list is refreshed exactly when it should be, without the need to insert any decision logic into the city getter. -- At least that's what I expected. In practice both list getters are called twice, even if that part of the page isn't updated at all. If the lists need to be fetched by a costly database operation or so, this is (potentially) highly inefficient.

The design pattern using "if (model) == null" is insufficient in this case, but can be of course be easily extended a bit to the following:



But this is exactly where we are adding the logic into the getters and setters, which we wanted to avoid in the first place. And which could easily be avoided if getters (and setters where needed) are only called once for each component and then only if the component needs updating (rerendering).
Mark Reyes
Ranch Hand

Joined: Jul 09, 2007
Posts: 426
Hi Paolo,

I am not exactly sure regarding your project constraints regarding 'inefficiencies' but maybe the links below could help.

link 1 and link 2

In my understanding, you just need to add a listener attribute to your f:ajax tag.

Your country list can be lazily initialized.. on change of the country list, just update your bean list.

So in short, you don't have to worry on how many times your getters and setters are called.

Thanks.
Paolo Rodeo
Greenhorn

Joined: Dec 11, 2010
Posts: 18

Hi Mark,
Thanks again for your time. I'm aware of these patterns. But with ajax things could be so much simpler... Still want to point out that if getters weren't needlessly called multiple times, design patterns could be much more simple, and my example was still a fairly simple one. Isn't that what engineering is about? Finding simple solutions for complex problems? Still wondering why JSF was implemented like that...
Regards, Paul.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15665
    
  15

JSF is based on the idea that backing beans will be POJOS. Part of the POJO contract is that the properties of the bean should not be directly accessible, but only accessed via get/set methods.

Another critical component of JSF is the JSF lifecycle. JSF is based on HTTP and HTTP is implemented via a series of request/response cycles. JSF handles requests and their responses via a pipeline process. At the beginning of the pipeline, a FacesContext object is created to manage the process. Associated with the FacesContext is a Component Tree, which is constructed or re-constructed as a 2-dimensional storage structure for accessing and rendering a View. The different stages in the pipeline reference this component tree and the component tree in turn references the backing beans and their properties.

As the request percolates down the pipeline, properties will be referenced. For example, one stage fires whatever valueChangeListeners need to be fired. The way to determine is a given listener needs to be fired is to compare the existing value with the incoming value. So the "get" method is invoked.

You could argue that all those values could be cached, but in fact, the backing bean itself is the cache. Why add extra complexity? Especially since sometimes the property value is changed as the pipeline flow progresses.

There's really not that much overhead to calling a get() method. Best practices are that getters should not initiate heavyweight operations nor should they have side-effects. As long as those constraints are observed, the fact that JSF calls getters more than once isn't really an issue.


Customer surveys are for companies who didn't pay proper attention to begin with.
Paolo Rodeo
Greenhorn

Joined: Dec 11, 2010
Posts: 18

Hi Tim,

OK, that's a good explanation to my last question. Thanks. So, after all I do have to put some more login in the bean, where I hoped this could be avoided. But I can live with that, understanding now that it keeps the JSF lifecycle a bit simpler.
Thanks, Paul.
Mark Reyes
Ranch Hand

Joined: Jul 09, 2007
Posts: 426
Hi,

Took time for me to look for this.

Maybe this link would help you http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why are getters called multiple times?
 
Similar Threads
jsf page data not changing
Please help - More specific question on JSF + jQuery
Simple custom security in JSF app
Form calling a session scoped backing bean constructor twice
visual jsf is about to kill me