3 Replies Latest reply on Dec 20, 2007 8:15 AM by pmuir

    missing conversation entry error

    gsegura

      Hello
      I'm having problems with a nested conversation, which after termination cannot restore the parent conversation only in 1 out of 3 similar (it seems so) cases.

      Its a case of edition of item A which has a collection of items B, when edition of item A starts I begin a conversation,
      inside that page every edition of items B is done inside a nested conversation.
      It works fine except in case of deletion of item B, which throws IllegalStateException: missing conversation entry.
      Here is the relevant code

      this is the extract from master page (company which holds a collection of employees):

      <!-- page for edition of Company -->
      <s:link value="Add employee" action="#{editorEmployee.create}" rendered="#{editorCompany.company.id!=null}"/>
      
      <rich:dataTable value="#{editorCompany.company.employees}" var="emp" rows="5" rendered="#{editorCompany.company.employees.size>0}">
       <h:column>
       <h:outputText value="#{emp.name}" />
       <br/>
       <s:link value="Edit" action="#{editorEmployee.select(emp)}" />
       </h:column>
      </rich:dataTable>
      


      this is the extract from detail page (employee data):
      <h:form id="f">
      
       <s:div rendered="#{editorEmployee.employee.id!=null}">
       <h:commandLink id="btnEliminar" value="" action="#{editorEmployee.delete}"/>
       </s:div>
      
       <s:decorate id="nameDecorate" template="/layout/edit.xhtml">
       <ui:define name="label">Name:</ui:define>
       <h:inputText id="name" value="#{editorEmployee.employee.name}" required="true">
       <a4j:support event="onblur" reRender="nameDecorate"/>
       </h:inputText>
       </s:decorate>
      
       <div class="buttonBox">
       <h:commandLink action="#{editorEmployee.save}">
       <h:graphicImage value="/img/btn/btn_save.gif" alt="save" styleClass="btn" />
       </h:commandLink>
      
       <h:commandLink action="#{editorEmployee.cancel}" immediate="true">
       <h:graphicImage value="/img/btn/btn_cancel.gif" alt="cancel" styleClass="btn" />
       </h:commandLink>
       </div>
      </h:form>
      


      the pages.xml:
      <page view-id="/admin/editorEmployee.xhtml">
       <navigation from-action="#{editorEmployee.save}">
       <rule if="#{editorEmployee.ok}">
       <redirect view-id="/admin/editorCompany.xhtml"/>
       </rule>
       <rule if="#{not editorEmployee.ok}">
       <redirect view-id="/admin/editorEmployee.xhtml"/>
       </rule>
       </navigation>
       <navigation from-action="#{editorEmployee.cancel}">
       <redirect view-id="/admin/editorCompany.xhtml"/>
       </navigation>
       <navigation from-action="#{editorEmployee.delete}">
       <redirect view-id="/admin/editorCompany.xhtml"/>
       </navigation>
       </page>
      



      finally, the EditorEmployee.java
      @Scope(ScopeType.CONVERSATION)
      @Name("editorEmployee")
      @Restrict("#{identity.loggedIn and s:hasRole('Administrator')}")
      public class EditorEmployeeAction {
       @In("#{editorSede.sede}")
       Company company ;
      
       @Begin(nested=true, flushMode=FlushModeType.MANUAL)
       public void select(Employee selectedEmployee) {
       log.info("selectEmployee, beginning conversation.id=#0",Conversation.instance().getId()) ;
       employee = entityManager.merge(selectedEmployee);
       }
      
       @Begin(nested=true, flushMode=FlushModeType.MANUAL)
       public void crear() {
       log.info("newEmployee, beginning conversation.id=#0",Conversation.instance().getId()) ;
       employee = new Employee(company, "") ;
       }
      
       @End
       public void delete() {
       company.getEmployees().remove(employee) ;
       entityManager.remove(employee) ;
       entityManager.flush() ;
       log.info("deleted employee #0, conversation.id: #1",employee,Conversation.instance().getId()) ;
       facesMessages.add("Employee deleted successfully.") ;
       }
      
       public void save() {
       boolean valid = validateEmployee(employee) ;
       ok = false ;
       if(valid) {
       //agregate to collection only if new employee
       if(employee.getId()==null)
       company.getEmployees().add(employee) ;
      
       entityManager.persist(employee);
       facesMessages.add("Employee data saved ok");
       ok = true;
       entityManager.flush() ;
      
       log.info("finishing nested conversation #0",Conversation.instance().getId());
       //conversation ended programmatically because in case validation fails the page is redisplayed
       //and conversation must continue until canceled or data ok.
       Conversation.instance().end() ;
       }
       }
      
       @End
       public void cancel() {
       log.info("editing employee canceled.") ;
       }
      


      Must part of this code works ok: creation or modification of employee, also if cancel action invoked.
      But something goes wrong with invocation of editorEmployee.delete(), the object is deleted correctly
      but the next view is not displayed, here is the complete stack trace:
      GRAVE: uncaught exception
      java.lang.IllegalStateException: missing conversation entry
       at org.jboss.seam.core.Conversation.flush(Conversation.java:124)
       at org.jboss.seam.core.Manager.flushConversationMetadata(Manager.java:882)
       at org.jboss.seam.faces.FacesManager.prepareBackswitch(FacesManager.java:278)
       at org.jboss.seam.jsf.SeamPhaseListener.beforeRenderResponse(SeamPhaseListener.java:470)
       at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseListener.java:146)
       at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:116)
       at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:222)
       at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
       at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
       at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
       at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
       at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
       at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
       at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44)
       at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
       at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
       at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
       at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)
       at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
       at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
       at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:834)
       at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:640)
       at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
       at java.lang.Thread.run(Unknown Source)
      


      I can not see what is the difference with delete action, respect the others, could someone please give some advice on this?



        • 1. Re: missing conversation entry error
          pmuir

          Does the delete method complete without exception?

          • 2. Re: missing conversation entry error
            gsegura

            I'm sorry, pretending to make the code clearer I removed a rich:modalPanel used for confirmation, and it turns out there was actually the error.

            as I posted before, the link was rendered by:

            <s:div rendered="#{editorEmployee.employee.id!=null}">
             <h:commandLink id="btnEliminar" value="delete" action="#{editorEmployee.delete}"/>
            </s:div>
            


            and the javascript code used to activate the link was:
            function doDelete() {
            window.location = document.getElementById('f:btnEliminar').href ;
            }



            I couldn't found a way to trigger the link programmatically, directly assigning window.location apparently has not the same effect.

            By time constraints to get around of my lack of knowledge of that js api I inserted a confirmation page instead.

            Would be nice to know the correct way to use a rich:modalPanel to ask for confirmation, and then invoke h:commandLink, though.

            anyway really thanks for your time




            • 3. Re: missing conversation entry error
              pmuir

              Try asking this question in the RichFaces forum, and post a track back here.