0 Replies Latest reply on Oct 18, 2007 1:41 PM by John Chesher

    Conversion/Validation error - other lists of entities in vie

    John Chesher Newbie

      I have a view that contains 4 separate backing beans, three of them being Lists of entities that are displayed using an <h:datatable> tag. My problem is that if I get a conversion or validation error on the form, the fields within the datatables are reverted to their values from when the form was originally rendered, before the user potentially changed values. The only case where they are not reverted is if the conversion/validation error occurs on a field within a datatable. In such case, all entries rendered within that datatable retain the value that the user changed them to (a partial victory!). To extend that thought, if I purposefully enter one invalid entry within each datatable, the entire form is redisplayed with the exact values that I entered.

      Anyone have an idea why this is happening and what I can do to resolve it such that, if any conversion/validation error on any field, the entire form, including all datatables, is redisplayed with the data as I entered it?

      FYI, I had a theroy that Seam or JSF had difficulty handling a form with multiple backing beans. So, one thing I tried was to create a POJO to act as a backing bean, put all 4 of the previous backing beans within it, define a factory method to load the new backing bean, then change the view to reference the new, consilidated backing bean. Unfortunately, same result...

      Thanks for any help you can provide!

      Here's the code, after I combined the 4 backing beans...
      The view:

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:hob="http://keyfact2.collegeview.com/tags/jsfcomponents"
       xmlns:si="http://jboss.com/products/seam/selectitems/taglib"
       xmlns:a="https://ajax4jsf.dev.java.net/ajax"
       xmlns:rich="http://richfaces.ajax4jsf.org/rich"
       xmlns:s="http://jboss.com/products/seam/taglib"
       template="/template_school_ugTab.xhtml">
      
       <ui:define name="content">
      
       <hob:editpage navarea="Undergraduate Student - Admissions">
       <h:form id="ugAdmissionsForm" name="ugAdmissionsForm">
       <f:facet name="beforeInvalidField">
       <s:message />
       </f:facet>
       <f:facet name="aroundInvalidField">
       <s:span styleClass="errorMessage" />
       </f:facet>
       <s:validateAll>
       <hob:sectionarea header_name="Requirements and Policies" name="a"
       fileName="/help/help.seam" />
       <table width="540" border="0" cellspacing="0" cellpadding="5">
       <tr>
       <td>
       <h:outputLabel for="admissionsPolicy">Admissions Policy</h:outputLabel>
       <s:decorate>
       <div>
       <h:selectOneListbox value="#{ugAdm.undergraduateAdmissions.admissionsPolicy}" id="admissionsPolicy" size="1">
       <s:selectItems value="#{admissionsPolicies}" var="admissionsPolicy" label="#{admissionsPolicy.name}" />
       <s:convertEntity/>
       </h:selectOneListbox>
       </div>
       </s:decorate>
       </td>
       <td>
       <h:outputLabel for="notificationPolicy">Notification Policy</h:outputLabel>
       <s:decorate>
       <div>
       <h:selectOneListbox value="#{ugAdm.undergraduateAdmissions.notificationPolicy}" id="notificationPolicy" size="1">
       <s:selectItems value="#{notificationPolicies}" var="notificationPolicy" label="#{notificationPolicy.name}" />
       <s:convertEntity/>
       </h:selectOneListbox>
       </div>
       </s:decorate>
       </td>
       <td>
       <h:outputLabel for="registrationPolicy">Registration Policy</h:outputLabel>
       <s:decorate>
       <div>
       <h:selectOneListbox value="#{ugAdm.undergraduateAdmissions.registrationPolicy}" id="registrationPolicy" size="1">
       <s:selectItems value="#{registrationPolicies}" var="registrationPolicy" label="#{registrationPolicy.name}" />
       <s:convertEntity/>
       </h:selectOneListbox>
       </div>
       </s:decorate>
       </td>
       </tr>
       <tr>
       <td>
       <h:selectBooleanCheckbox id="earlyDecision" value="#{ugAdm.undergraduateAdmissions.earlyDecision}"/>
       <h:outputLabel for="earlyDecision">Early Decision</h:outputLabel>
       </td>
       </tr>
       </table>
       <hob:sectionarea header_name="High School Prerequisites" name="b" fileName="/help/help.seam" />
       <h:dataTable var="prerequisite" value="#{ugAdm.undergraduateHighSchoolPrerequisites}">
       <h:column>
       <f:facet name="header" align="left">Name </f:facet>
       <div>
       <h:outputText value="#{prerequisite.prerequisiteType.name}"/>
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">Years Required </f:facet>
       <div>
       <s:decorate>
       <h:inputText value="#{prerequisite.yearsRequired}"/>
       </s:decorate>
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">Years Recommended </f:facet>
       <div>
       <s:decorate>
       <h:inputText value="#{prerequisite.yearsRecommended}" label="#{prerequisite.prerequisiteType.name}"/>
       </s:decorate>
       </div>
       </h:column>
       </h:dataTable>
      
       <hob:sectionarea header_name="Qualifications" name="c" fileName="/help/help.seam" />
       <h:dataTable var="qualificationArray" value="#{ugAdm.undergraduateQualifications}">
       <h:column>
       <f:facet name="header" align="left">Name </f:facet>
       <div>
       <h:outputText value="#{!empty qualificationArray[0] ? qualificationArray[0].qualificationType.name : qualificationArray[1].qualificationType.name}" />
       </div>
       </h:column>
       <h:column>
       <div>
       <h:graphicImage alt="....." url="/_img/transparentOnePixel.gif" height="1" width="20" />
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">Freshman </f:facet>
       <s:decorate>
       <h:selectOneListbox size="1" value="#{qualificationArray[0].requiredOptionalRecommended}">
       <s:convertEntity/>
       <s:selectItems value="#{requiredOptionalRecommended}" var="singleRequiredOptionalRecommended" label="#{singleRequiredOptionalRecommended.name}" noSelectionLabel="Choose One"/>
       </h:selectOneListbox>
       </s:decorate>
       </h:column>
       <h:column>
       <div>
       <h:graphicImage alt="....." url="/_img/transparentOnePixel.gif" height="1" width="20" />
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">Transfer </f:facet>
       <s:decorate>
       <h:selectOneListbox size="1" value="#{qualificationArray[1].requiredOptionalRecommended}">
       <s:convertEntity/>
       <s:selectItems value="#{requiredOptionalRecommended}" var="singleRequiredOptionalRecommended" label="#{singleRequiredOptionalRecommended.name}" noSelectionLabel="Choose One"/>
       </h:selectOneListbox>
       </s:decorate>
       </h:column>
       </h:dataTable>
      
       <table>
       <tr>
       <td>Application Fee</td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.applicationFee}"/>
       </s:decorate>
       </td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.transferApplicationFee}"/>
       </s:decorate>
       </td>
       </tr>
       <tr>
       <td>Deposit</td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.deposit}"/>
       </s:decorate>
       </td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.transferApplicationDeposit}"/>
       </s:decorate>
       </td>
       </tr>
       <tr>
       <td>Deadline (mm/dd/yyyy)</td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.deadline}" maxlength="10">
       <f:convertDateTime pattern="MM/dd/yyyy" />
       </h:inputText>
       </s:decorate>
       </td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.transferdeadline}" maxlength="10">
       <f:convertDateTime pattern="MM/dd/yyyy" />
       </h:inputText>
       </s:decorate>
       </td>
       </tr>
       </table>
       <hob:sectionarea header_name="Freshman Applications" name="d" fileName="/help/help.seam" />
       <table>
       <tr>
       <th>Received</th>
       <th>Accepted</th>
       <th>Enrolled</th>
       </tr>
       <tr>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.applicationsReceived}"/>
       </s:decorate>
       </td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.applicationsAccepted}"/>
       </s:decorate>
       </td>
       <td>
       <s:decorate>
       <h:inputText value="#{ugAdm.undergraduateAdmissions.applicationsEnrolled}"/>
       </s:decorate>
       </td>
       </tr>
       </table>
       <hob:sectionarea header_name="Test Scores" name="e" fileName="/help/help.seam" />
       <h:dataTable value="#{ugAdm.undergraduateTests}" var="test">
       <h:column>
       <f:facet name="header" align="left">Name </f:facet>
       <div>
       <h:outputText value="#{test.testType.name}"/>
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">High </f:facet>
       <div>
       <s:decorate>
       <h:inputText value="#{test.high}"/>
       </s:decorate>
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">Low </f:facet>
       <div>
       <s:decorate>
       <h:inputText value="#{test.low}"/>
       </s:decorate>
       </div>
       </h:column>
       <h:column>
       <f:facet name="header" align="left">Average </f:facet>
       <div>
       <s:decorate>
       <h:inputText value="#{test.average}"/>
       </s:decorate>
       </div>
       </h:column>
       </h:dataTable>
       <hob:sectionarea header_name="Other" name="f" fileName="/help/help.seam" />
       <br/>
       <div>
       <h:outputLabel for="gpaAverage">GPA Average</h:outputLabel>
       <s:decorate>
       <h:inputText id="gpaAverage" value="#{ugAdm.undergraduateAdmissions.gpaAverage}"/>
       </s:decorate>
       </div>
       <br/>
       <div>
       <s:decorate>
       <h:selectBooleanCheckbox id="satRecentered" value="#{ugAdm.undergraduateAdmissions.satRecentered}"/>
       </s:decorate>
       <h:outputLabel for="satRecentered">SAT Recentered</h:outputLabel>
       <s:decorate>
       <h:selectBooleanCheckbox id="clepCredit" value="#{ugAdm.undergraduateAdmissions.clepCredit}"/>
       </s:decorate>
       <h:outputLabel for="clepCredit">CLEP Credit</h:outputLabel>
       <s:decorate>
       <h:selectBooleanCheckbox id="apCredit" value="#{ugAdm.undergraduateAdmissions.apCredit}"/>
       </s:decorate>
       <h:outputLabel for="apCredit">AP Credit</h:outputLabel>
       <s:decorate>
       <h:selectBooleanCheckbox id="commonApplication" value="#{ugAdm.undergraduateAdmissions.commonApplication}"/>
       </s:decorate>
       <h:outputLabel for="commonApplication">Common Application</h:outputLabel>
       <s:decorate>
       <h:selectBooleanCheckbox id="applicationPriority" value="#{ugAdm.undergraduateAdmissions.applicationPriority}"/>
       </s:decorate>
       <h:outputLabel for="applicationPriority">Application Priority</h:outputLabel>
       </div>
       <hob:sectionarea header_name="Comments" name="g" fileName="/help/help.seam" />
       <s:decorate>
       <h:inputTextarea id="Comments" value="#{ugAdm.undergraduateAdmissions.comments}" rows="5" cols="60" />
       </s:decorate>
       <table id="buttons" width="540" border="0" cellspacing="0" cellpadding="5">
       <tr>
       <td align="center">
       <h:commandButton styleClass="buttons" id="save" value="#{messages['saveButton']}"
       action="#{undergraduateAction.saveAdmissionsInforamation}" onclick="stopDirtyCheck(this);"/>
       <h:commandButton styleClass="buttons" id="cancel" value="#{messages['cancelButton']}"
       action="#{undergraduateAction.resetAdmissionsInforamation}" immediate="true" onclick="if(confirmCancel()) { stopDirtyCheck(this); return true } else { return false; }" />
       </td>
       </tr>
       </table>
       </s:validateAll>
       </h:form>
       </hob:editpage>
      
       <script>
       var temp = new Array();
       temp.push($('ugAdmissionsForm'));
       temp.push(true);
       forms.push(temp);
       </script>
      
       </ui:define>
      </ui:composition>
      


      The backing bean:
      package com.hobsons.keyfact.backing;
      
      import java.util.List;
      
      import com.hobsons.keyfact.model.HighSchoolPrerequisite;
      import com.hobsons.keyfact.model.Qualification;
      import com.hobsons.keyfact.model.Test;
      import com.hobsons.keyfact.model.UndergraduateAdmissions;
      
      public class UgAdmissionsBacking
      {
       private UndergraduateAdmissions undergraduateAdmissions;
       private List<HighSchoolPrerequisite> undergraduateHighSchoolPrerequisites;
       private List<Qualification[]> undergraduateQualifications;
       private List<Test> undergraduateTests;
      
      
       public UgAdmissionsBacking() {}
      
       public UgAdmissionsBacking(UndergraduateAdmissions undergraduateAdmissions, List<HighSchoolPrerequisite> undergraduateHighSchoolPrerequisites, List<Qualification[]> undergraduateQualifications, List<Test> undergraduateTests)
       {
       super();
       this.undergraduateAdmissions = undergraduateAdmissions;
       this.undergraduateHighSchoolPrerequisites = undergraduateHighSchoolPrerequisites;
       this.undergraduateQualifications = undergraduateQualifications;
       this.undergraduateTests = undergraduateTests;
       }
      
       public UndergraduateAdmissions getUndergraduateAdmissions() {
       return undergraduateAdmissions;
       }
      
       public void setUndergraduateAdmissions(
       UndergraduateAdmissions undergraduateAdmissions) {
       this.undergraduateAdmissions = undergraduateAdmissions;
       }
      
       public List<HighSchoolPrerequisite> getUndergraduateHighSchoolPrerequisites() {
       return undergraduateHighSchoolPrerequisites;
       }
      
       public void setUndergraduateHighSchoolPrerequisites(
       List<HighSchoolPrerequisite> undergraduateHighSchoolPrerequisites) {
       this.undergraduateHighSchoolPrerequisites = undergraduateHighSchoolPrerequisites;
       }
      
       public List<Qualification[]> getUndergraduateQualifications() {
       return undergraduateQualifications;
       }
      
       public void setUndergraduateQualifications(
       List<Qualification[]> undergraduateQualifications) {
       this.undergraduateQualifications = undergraduateQualifications;
       }
      
       public List<Test> getUndergraduateTests() {
       return undergraduateTests;
       }
      
       public void setUndergraduateTests(List<Test> undergraduateTests) {
       this.undergraduateTests = undergraduateTests;
       }
      
      
       /**
       * @see java.lang.Object#equals(Object)
       */
       public boolean equals(Object object) {
      
       if(this == object) {
       return true;
       }
       else if((object == null) || (object.getClass() != this.getClass())) {
       return false;
       }
       else {
       return this.toString().equals(object.toString());
       }
       }
      
      
       /**
       * @see java.lang.Object#hashCode()
       */
       public int hashCode() {
       return this.toString().hashCode();
       }
      
       /**
       * @see java.lang.Object#toString()
       */
       @Override
       public String toString() {
      
       return
       "ClassName:" + this.getClass().getName()
       + undergraduateAdmissions.toString();
       }
      
      }


      And the factory method:
      @Factory("ugAdm")
       public UgAdmissionsBacking getUgAdm()
       {
       UgAdmissionsBacking ugAdm = new UgAdmissionsBacking();
       ugAdm.setUndergraduateAdmissions(getUndergraduateAdmissions());
       ugAdm.setUndergraduateHighSchoolPrerequisites(getHighSchoolPrerequisites());
       ugAdm.setUndergraduateQualifications(getQualifications());
       ugAdm.setUndergraduateTests(getTests());
       conversationContext.set("ugAdm", ugAdm);
       return ugAdm;
       }