Life Cycle Question: Order of evaluation of component data

Hello,

I created a page with a table component and a drop down component. A change in the value of the drop down should result in a change of the table component.

For the drop down value I created a getter getNumberOfAdults() and setter setNumberOfAdults(String xyz) method. This works fine.

The table component is related to a Table Data Provider which has the array property set to rlZiel. There is a "handmade" method in the SessionBean1

public ziel[] getRlZiel()

which returns an array for the Data Provider. In getRlZiel() the value of the drop down is used to manipulate the data in the array.

Calling this page renders the expected values in the table.

Now the problem starts: I change the value of the drop down and send the form. The debugger tells me that getRlZiel() is called first and some time after that the setter setNumberOfAdults(String xyz). So of course the reloaded page displays the changed value of the drop down but still the old data in the table. Only after resubmitting the form again the right data is shown in the table.

I set the drop down to be an immediate component. But still the debugger tells me that getRlZiel() is called first and some time after that the setter setNumberOfAdults(String xyz).

Why is this so? My understanding of the "immediate" property was that the value setter is called after the ApplyRequestPhase. Am I wrong?

Any hint & help greatly appreciated,

Juergen

How can I influence the order of evaluation of component data?

[1594 byte] By [bookon] at [2007-11-26 9:23:31]
# 1

As this question about the life cycle is a very fundamental one: Does anybody has an idea? Or at least a hint where I could read some information about this?

I already bought the "core JAVA SERVER FACES" book by David Geary and Cay Horstmann, but the relevant pages about the life cycle do not go into detail about this.

Any other book or online resource I should consult?

I am of course willing to share my insights with everbody here, as soon as I get some... :)

Juergen

bookon at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 2
On the dropdown, did you enable the Auto Submit on Change (right-click on the Dropdown and select this menuitem)John
jawbe at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 3
Not sure this will help, but I would take a different approach. I would add a method to my subclassed table data provider named refreshList(arg).In the prerender method I would call:myTableDataProvider.refreshList(myDropDown.getSelected());Just a thought.
jetsons at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 4
Hallo John,> On the dropdown, did you enable the Auto Submit on> Change > (right-click on the Dropdown and select this> menuitem)Yes, I did both. I tried it with and without. Both didn't work.Juergen
bookon at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 5

> Not sure this will help, but I would take a different

> approach. I would add a method to my subclassed table

> data provider named refreshList(arg).

>

> In the prerender method I would call:

>

> myTableDataProvider.refreshList(myDropDown.getSelected

> ());

>

I tried this and set a breakpoint in the prerender method.

Unfortunately the prerender method is called after the other two methods mentioned above.

Is there a tool with which I can check which method is called in which lifecycle phase?

I read the phase event example in "Core JavaServer Faces - chapter 7 pg.296-304" using a phase event listener. This should help to analyze this behaviour. But I am not sure how I should integrate the phase event listener in our application.

I'll report any progress here.

Juergen

bookon at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 6

I apologize for not explaining myself well. What I was trying to say is that, because you know that by the time you get to prerender, dropDown1.getSelected returns the correct value, that is a good time to fill the array up with the values that are based on what was selected.

Another alternative is to create a dropDown1_processValueChange(ValueChangeEvent event) event handler for your drop down and store the value in a sessionBean property. Then have the getRlZiel() get the value out of the session bean property instead of the getNumberOfAdults() method.

I know that doesn't answer your lifecycle question. Hopefully, someone else will answer those questions.

jetsons at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 7

That kind of thing happens because of the UPDATE_MODEL_VALUES phase.

When this phase occurs, the old model (which contains your old data table fields) overwrites the current data table values.

An approach would be:

public void dropDown_processValueChange(ValueChangeEvent event) {

PhaseId phaseId = event.getPhaseId();

if (phaseId.equals(PhaseId.ANY_PHASE)) {

event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);

event.queue();

} else if (phaseId.equals(PhaseId.UPDATE_MODEL_VALUES)) {

if (event.getNewValue() != null) {

//if it's the update model values phase, then I'm ready

//to update my datatable

callDataTableUpdateMethod();

}

}

}

Hope this helps.

Message was edited by:

Gabriel.Galvao

GabrielGalvao at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 8
Also,creator crew. This seems like a small "hack". Why do we need to do this kind of "hacking"? I've seen other JSF users ask this same question.
GabrielGalvao at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 9
I'm afraid the requirements are not clear enough. Is the table read-only or read-write? And how is the dropdown selection supposed to influence the table? Also, what is a Ziel? Please give as much information about the functional requirements as possible. Then we can explain the
mbohm at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 10
This article might help. http://developers.sun.com/prodtech/javatools/jscreator/reference/techart/2/app_ model.htmlthankssrinivasCreator Team
srinivasscreen at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 11

I think I understand the original post enough to summarize it

Table component is bound to a data provider which is bound to a session bean array (let's call it dataArray).

Drop down list selected property is bound to a session bean property (lets' call it selectedValue). The drop down list is set to auto-submit on change and the drop down list's immediate is set to true.

The getter for the array (getDataArray) uses selectedValue to determine what to put in the array.

The posters problem is that getDataArray is called before setSelectedValue, even though the drop down list has immediate set to true.

The poster has already read up on the JSF life cycle to try and figure out why the above has happened, but has not been able to figure it out, so he/she needs someone to explain why this is so.

jetsons at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 12
Isn't it the UPDATE MODEL VALUES phase? The set method is called before the update model, thus, making any changes to be overwritten by subsequent set calls during update model values.I've been through this problem and I've overcome it with the code shown some posts
GabrielGalvao at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 13

> I set the drop down to be an immediate component. But

> still the debugger tells me that getRlZiel() is

> called first and some time after that the setter

> setNumberOfAdults(String xyz).

Look in the _init() method. Do you see something like the following:

objectArrayDataProvider1.setArray((java.lang.Object[])getValue("#{SessionBean1.rlZiel}"));

This is why the call to getRlZiel() is being called way before the call to setNumberOfAdults(String xyz).

So, I still suggest that you refresh/populate the array in the prerender method.

jetsons at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 14

> Look in the _init() method. Do you see something like

> the following:

> >objectArrayDataProvider1.setArray((java.lang.Object[])getValue("#{SessionBean1.rlZiel}"));

>

> This is why the call to getRlZiel() is being called

> way before the call to setNumberOfAdults(String

> xyz).

>

> So, I still suggest that you refresh/populate the

> array in the prerender method.

Correct! You got it. It works now.

I just copied the call from _init to prerender.

I also removed it from the _init method.

Thank you for your help, Chris.

Juergen

To answer the questions of mbohm:

jetsons exactly describes the problem in his posting from 14.08.2006 23:31

The displayed table is read only, but each row contains a button to select this row and to navigate to the next page.

bookon at 2007-7-6 23:58:09 > top of Java-index,Development Tools,Java Tools...
# 15
> I also removed it from the _init method.This is bad for using the Visual Designer. It starts displaying annoying errors.So for design time I suggest leaving it there, but remove it for deployment on the life system.Juergen
bookona at 2007-7-21 15:17:54 > top of Java-index,Development Tools,Java Tools...
# 16

I am worried that by your moving the code to prerender, other problems might happen. Let't hope not.

Hopefully before the end of the week the Hibernate tutorial will get published on http://developers.sun.com/prodtech/javatools/jscreator/learning/tutorials/index .jsp. This shows how to use an object list data provider with a refresh method that you call from prerender like I was suggesting.

Glad I was able to resolve your problem and I learned something too. Lot's of engineers jumped in to help me help you.

jetsonsa at 2007-7-21 15:17:54 > top of Java-index,Development Tools,Java Tools...