0 Replies Latest reply on Dec 1, 2011 12:14 PM by dzakharov.dmitri.zakharov.gmail.com

    Seam2 to Seam3: edit to view page conversational navigation

    dzakharov.dmitri.zakharov.gmail.com

      Hello everybody,


      I am migrating my Seam2 application to JavaEE6/JBoss7/Seam3. The Seam2 application has the following workflow for adding an entity. For example I navigate to exporterEdit.xhtml page, input information in the fields and click submit button. The Exporter entity is persisted to the database and I am directed to exporter.xhtml view which displays the message that the entity has been successfully saved and displays the details of the newly persisted entity. By inspecting the code I observed that the navigation is managed in ExporterEdit.page.xml file as follows:


      ...
        <begin-conversation join="true" flush-mode="MANUAL"/>
         <param name="exporterFrom"/>
         <param name="exporterExporterId" value="#{exporterHome.exporterExporterId}"/>
      
      
         <navigation from-action="#{exporterHome.persist}">
            <rule>
               <end-conversation/>
               <redirect view-id="/Exporter.xhtml"/>
            </rule>
         </navigation>
      ...
      


      Now in my JavaEE6 application, (since I do not have the posibility to demarcate conversation a la Seam2 in XML file) I initialize conversation in my exporterEdit.xhtml view as follows:


      ...
      <ui:define name="content">
          <f:metadata>
                  <f:viewParam name="id" value="#{exporterHome.id}" />
              <s:viewAction action="#{exporterHome.init(true)}"/>
          </f:metadata>
      
          <h:form id="exporter" styleClass="edit">
              <rich:panel>
               <f:facet name="header">#{exporterHome.managed ? 'Edit' : 'Add'} Exporter</f:facet>
               <ol>
                   <li id="identifierField">
                          <h:outputLabel styleClass="name" 
                              value="#{messages['exporter.identifier']}" 
                              for="identifier">
                        <h:outputText value="*" styleClass="required" />
                    </h:outputLabel>
                          <h:inputText id="identifier" required="true" size="6"
                               maxlength="6" 
                               value="#{exporterHome.instance.identifier}">
                            <f:validateLength minimum="6" maximum="6" />
                     <f:validateRequired />
                     <rich:validator />
                    </h:inputText><rich:message for="identifier" />
                       </li>
      
                <li id="nameField">
                          <h:outputLabel styleClass="name"
                        value="#{messages['exporter.name']}" for="name">
                     <h:outputText value="*" styleClass="required" />
                    </h:outputLabel> 
                          <h:inputText id="name" required="true"
                              size="35" maxlength="70" 
                              value="#{exporterHome.instance.name}">
                           <f:validateLength maximum="70" />
                     <f:validateRequired />
                     <rich:validator />
                    </h:inputText><rich:message for="name" />
                       </li>
                </ol>
              </rich:panel>
           
               <div class="actionButtons">
                <a4j:commandButton id="save" value="Save" 
                       action="#{exporterHome.insert()}" oncomplete="" />
           </div>
          </h:form>
      </ui:define>
      ....
      



      The method call #{exporterHome.init(true)} from the extract above initializes a long running conversation (and this works fine).


      ...
          <s:viewAction action="#{exporterHome.init(true)}"/>
      ...
      



      Since I can not demarcate my conversation boundaries in XML navigation rules (defined in faces-config.xml) which look as follows:


      ...
      <navigation-rule>
           <from-view-id>/view/exporterEdit.xhtml</from-view-id>
           <navigation-case>
                <from-outcome>persisted</from-outcome>
                <to-view-id>/view/exporter.xhtml</to-view-id>
                <redirect include-view-params="true" />
           </navigation-case>
      </navigation-rule>
      ...
      



      I do that in #{exporterHome.insert()} method as follows:


      ...
          public String insert() {
           exporterDAO.insert(getInstance());
      
           log.debug(String.format("inserted %s", getInstance()));
                
           exporterDAO.flush();
           endConversation(); 
                
           return "persisted";
          }
      ...
      



      But when I execute this code I am redirected to exporter.xhml view but the entity details are not displayed (below is the beginning of exporter.xhtml view):


      ...
      <ui:define name="content">
          <f:metadata>
              <f:viewParam name="id" value="#{exporterHome.id}" />
          </f:metadata>
          <h:form>
              <rich:panel>
               <f:facet name="header">Exporter Details</f:facet>
               <ol class="entityFieldsList">
                   <li class="entityField">
                    <h:outputLabel styleClass="name" 
                            value="#{messages['entity.id']}" />
                    <h:outputText value="#{exporterHome.instance.id}" />
                </li>
      ...
      



      But if I comment out the call to endConversation() method above the details are displayed properly. It seams that Seam2 is closing the conversation after the details view is rendered or doing some extra work under the hood.


      So the question is how do I achieve the same in JavaEE6/Seam3 application? I want to add entity and get redirected to the details pages that displays the newly entered entity. How do I properly close conversation in this case?


      Thank you,