NOTE: This issue has been fixed in JSF 2.2, changing the way how the hidden view state field is generated to:
<input type="hidden" name="javax.faces.ViewState" id="j_id__v_0:javax.faces.ViewState:1" value="..." />
In JSF 2.1 or 2.0, suppose the following example:
<!-- ... --> <h:form id="form1"> <!-- ... --> <h:commandButton value="Partial"> <f:ajax execute="@this" render="@this" /> </h:commandButton> </h:fom> <!-- ... --> <h:form id="form2"> <!-- ... --> <h:commandButton value="Normal Submit" /> </h:form>
Note each form has its own javax.faces.ViewState hidden field. When a partial ajax request is triggered, the hidden field of "form1" is updated, but the one in "form2" it is not.
This problem cause state saving problems, because old states are restored. For example, if server side state saving is used and org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION is set in 5, and you click more than 4 times "Partial" button and then try "Normal Submit" button, a ViewExpiredException is thrown, because that old state was already discarded.
See these issues for more details:
- MYFACES-2881 Server state saving with two forms, ajax and normal request is broken
- MYFACES-3159 ViewExpiredException occurs if you heavy use ajax within more than one form
In MyFaces Core there is a fix for this one. Just try add this after your jsf.js include
This enable and special mode that find and update javax.faces.ViewState per ajax request, solving the problem.