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

  <script type="text/javascript">
      //fixup for an issue of the jsf2.0 and 2.1 ajax spec to deal with multiple forms per page
      window.myfaces = window.myfaces || {};
      myfaces.config = myfaces.config || {};
      myfaces.config.no_portlet_env = true;
  </script>

This enable and special mode that find and update javax.faces.ViewState per ajax request, solving the problem.

  • No labels