Validation error corrupts component tree?

I've got a strange problem trying to use validation on input fields.

The basic setup is as follows:

I've got a page divided into two parts with separate h:form tags, the one holding a dataTable with some elements and the other showing the element details in inputFields once an item is selected in the dataTable via a commandLink. A commandButton on the detail side allows you to update the values of the selected item which is being reflected in the dataTable on reload. So far so good.

Here comes the strange part:

All the inputFields are marked required. Now once you leave a field empty and try to submit the form, you get a validation error as expected. BUT if you now select a different element from the dataTable, ONLY the field whose validation formerly failed is being updated, the other fields still show the same value as before. The backing bean method that belongs to the commandLink is being executed, and the underlying data object of the input fields is being set properly, only the values in the component tree aren't updated. This behaviour persists until you enter a valid value in the formerly invalid input field and submit. Debugging shows that as long as at least one field has had validation errors, only the getter of these backing beans properties are being invoked during render response phase, as opposed to the "normal" case where the getters of all the backing beans properties are being called.

For some reason, the render response phase seems to ignore the other components in the component tree when there was some validation error on one or more fields.

Another interesting observation:

This is the behaviour if I don't specify an action attribute in the commandLink selecting an element from the dataTable, as I want to return to the same page again. But if I define a navigation case that brings me to the same page and put that into the action attribute, the problem doesn't occur. Unfortunately this is no option for me, as I'm aiming to do all this with ajax.

I've created a simple example so you can try out yourself:

test.jsp:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<html>

<head>

<title>validator test</title>

</head>

<body>

<f:view>

<h:form id="form1">

<h:dataTable id="table" value="#{bean.datas}" var="data" binding="#{bean.table}" border="1">

<h:column>

<h:commandLink actionListener="#{bean.selectData}" value="#{data.string1}" />

</h:column>

<h:column>

<h:outputText value="#{data.string2}" />

</h:column>

</h:dataTable>

</h:form>

<hr />

<h:form id="form2">

<h:inputText value="#{bean.data.string1}" id="field1" required="true" />

<h:inputText value="#{bean.data.string2}" id="field2" required="true"/>

<h:commandButton value="submit" />

</h:form>

</f:view>

</body>

</html>

Bean.java:

needs to be defined infaces-config.xml as bean "bean" withsession scope

import java.util.ArrayList;

import java.util.List;

import javax.faces.component.html.HtmlDataTable;

import javax.faces.event.ActionEvent;

publicclass Bean{

private Data data;

private List<Data> datas;

private HtmlDataTable table;

public Bean(){

datas =new ArrayList<Data>();

datas.add(new Data("data1value1","data1value2"));

datas.add(new Data("data2value1",""));

}

publicvoid selectData(ActionEvent event){

data = (Data)table.getRowData();

}

public List<Data> getDatas(){

return datas;

}

public Data getData(){

return data;

}

publicvoid setData(Data data){

this.data = data;

}

public HtmlDataTable getTable(){

return table;

}

publicvoid setTable(HtmlDataTable table){

this.table = table;

}

publicclass Data{

private String string1;

private String string2;

public Data(String string1, String string2){

this.string1 = string1;

this.string2 = string2;

}

public String getString1(){

return string1;

}

publicvoid setString1(String value){

string1 = value;

}

public String getString2(){

return string2;

}

publicvoid setString2(String value){

string2 = value;

}

}

}

My system setup:

WinXP Professional

JDK 1.6.0-b105

Tomcat 5.5.20 (also tried 6.0.7)

JSF RI 1.1.02_b08 (also tried 1.2_04-b10-p01, different but anyway not expected behaviour with MyFaces 1.1.5)

Thanks for any input,

Harry.

[7600 byte] By [hstangla] at [2007-11-27 7:56:39]
# 1
Is there noone here who can tell me if this is behavior like specified or if I miss some point?A possible solution seems to be telling JSF programmatically to rebuild the view root. Does anyone if this is possible?
hstangla at 2007-7-12 19:38:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...