Hello,
Some other user posted a similar question on this forum recently and even filed a bug (https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=82), but there's no response yet. The symptom is that if user clicks a commandButton with immediate="true", inputText fields in the form seem to be always using "cached" value and does not call the backing bean's getter method bound to the inputText fields to get their latest values. I would like to give another simple test case to illustrate this problem, and hopefully somebody can suggest some solution to this problem:
First, create a JSF page test.jsp as follows:
<f:view>
<h:form>
<font color="red"><h:messages/></font><p>
Field 1: <h:inputText value="#{test.field1}"/><br>
Field 2: <h:outputText value="#{test.field2}"/><br>
<h:commandButton value="cancel" action="#{test.cancel}" immediate="true"/>
<h:commandButton value="save" action="#{test.save}"/>
</h:form>
</f:view>
Then, the backing bean class is defined as follows:
public class Test {
public String cancel() {
System.out.println("cancel() called");
return "homepage";
}
public String save() {
System.out.println("save() called");
return "homepage";
}
private String field1;
private String field2;
public String getField1() {
field1 = readField1FromDatabase(); // read field1 from database
System.out.println("getField1() called; return " + field1);
return field1;
}
public void setField1(String field1) {
System.out.println("setField1() called with " + field1);
this.field1 = field1;
}
public String getField2() {
field2 = readField2FromDatabase(); // read field2 from database
System.out.println("getField2() called; return " + field2);
return field2;
}
public void setField2(String field2) {
System.out.println("setField2() called with " + field2);
this.field2 = field2;
}
}
Although not shown here, the methods readField1FromDatabase() and readField2FromDatabase() simply get field1 and field2's values from database -- let's assume there's a table with one row, and two fields, field1 and field2, and these two methods simply read from that table.
The relevent part of faces-cofig.xml is as follows:
<navigation-rule>
<from-view-id>/test.jsp</from-view-id>
<navigation-case>
<from-outcome>homepage</from-outcome>
<to-view-id>/homepage.jsp</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
Now let's do the following:
1. Access url test.faces. Now I can see field1 and field2 both display correct value obtained from database.
2. Click "cancel" button, and I see homepage.faces.
3. Go to database, and change the values of field1 and field2 in the database.
4. Type in the url for test.faces or click a href link pointing to test.faces. I expect to getField1() and getField2() methods to be called and new values of field1 and field2 I updated in step 3 should be displayed. However, from the System.out.println() debug message, I can see that getField1() method is not called at all, and in my browser, I still see the OLD value of field1. Method getField2() is called, and its new value is displayed correctly.
The difference between field1 and field2 is that former is an inputText, and the later is an outputText. The behavior of outputText is correct, while inputText is not.
The above scenario is not artificial. This happens in our real application and we are deeply troubled by this issue. Any help will be greatly appreicated!
- lhh