3 Replies Latest reply on Jul 2, 2012 10:12 AM by flaubertg

    TransactionRequiredException: no transaction is in progress

    Dmitri Zakharov Newbie

      Hello everybody,


      I get TransactionRequiredException (the complete stack trace is at the end of the message) in the following scenario.
      I generated a project using seam generate from the existing database, using


      Seam : 2.1.1.GA
      JBoss: 5.1.0.GA



      The detailed description of the problem is below. But briefly, I have a result list where I can select multiple records by clicking checkbox and perform Send selected action, which simply changes the status of selected records and updates the database. Any suggestions how to fix this are really appreciated. Thank you.


      I have a ClaimList view which is backed up by claimList Seam component, which is an EntityQuery:


      @Name("claimList")
      @Scope(ScopeType.CONVERSATION)
      public class ClaimList extends EntityQuery<Claim> {
      
           private static final String EJBQL = "select claim from Claim claim";
      
           private static final String[] RESTRICTIONS = {
                "claim.claimStatus.statusId = #{claimCriteria.status.statusId}",
                "claim.createDate >= #{claimCriteria.afterDate}",
                "claim.createDate <= #{claimCriteria.beforeDate}"
           };
      
           private Claim claim = new Claim();
      
           public ClaimList() {
                setEjbql(EJBQL);
                setRestrictionExpressionStrings(Arrays.asList(RESTRICTIONS));
                setMaxResults(25);
           }
      
           public Claim getClaim() {
                return claim;
           }
      }



      In the ClaimList view I added a checkbox at the beginning of each claim row as follows:


          <rich:dataTable id="claimList"
                      var="_claim"
                    value="#{claimList.resultList}"
                 rendered="#{not empty claimList.resultList}"
                 rowClasses="rvgRowOne,rvgRowTwo">
      
             <h:column>
                   <f:facet name="header">&#160;</f:facet>
                   <h:selectBooleanCheckbox value="#{_claim.selected}" style="margin: 0;"/>
              </h:column>
      ...
      



      The user has an option to select All/None claims using some simple JavaScript as follows:


      <s:div rendered="#{not empty claimList.resultList}" style="padding-top:3pt">
         <h:outputText value="Select: " />#{'  '}
         <h:commandLink value="All" onclick="selectCheckbox(document.claimResultList, true); return false;"/><h:outputText value=", " />
          <h:commandLink value="None" onclick="selectCheckbox(document.claimResultList, false); return false;"/>
      </s:div>
      



      And than I added the action button to Send selected claims, as follows:


      <h:commandButton action="#{multiClaimListAction.sendSelected}" value="Send selected"/>
      



      The navigation directive in ClaimList.page.xml looks as follows:


         <navigation from-action="#{multiClaimListAction.sendSelected}">
            <rule>
               <redirect view-id="/ClaimList.xhtml"/>
            </rule>
         </navigation>
      



      What this action is supposed to do is to update the status of the selected Claims and persist the update to the database. multiClaimListAction component is defined as follows:


      @Name("multiClaimListAction")
      public class MultiClaimListAction {
      
          @Logger private Log log;
          @In protected FacesMessages facesMessages;
          @In Map<String, String> messages;
          @In protected ClaimList claimList;
           
          @Transactional
          public String sendSelected() {
           boolean foundSelected = false;
           boolean invalidStatus = false;
           String status = null;
           ArrayList<Claim> selected = new ArrayList<Claim>();
                
           for (Claim c : claimList.getResultList()) {
               if (c.isSelected()) {
                foundSelected = true;
                log.info("selected CLAIM_ID: " + c.getClaimId());
                status = c.getClaimStatus().getName();
                if ("NEW".equalsIgnoreCase(status) || 
                              "REJECTED".equalsIgnoreCase(status)) {
                    selected.add(c);
                } else {
                    invalidStatus = true;
                               
                }
               }
           }
      
           if (invalidStatus) {
                facesMessages.add(Severity.ERROR, "only NEW and REJECTED claims can be sent, select claims and try again.");
                return null;
           } else if (! foundSelected) {
                facesMessages.add(Severity.WARN, messages.get("claim.noSelection"));
                return null;
           } else {
                // change status to READY and update database records
                EntityManager em = claimList.getEntityManager();
                Claim claimEntity = null;
                     
                for (Claim c : selected) {
                     claimEntity = em.find(Claim.class, c.getClaimId());
                     if claimEntity.getClaimStatus().getName().equalsIgnoreCase("NEW")
                         || claimEntity.getClaimStatus().getName().equalsIgnoreCase("REJECTED")) {
                          claimEntity.setClaimStatus(new ClaimStatus(
                               Status.READY.getId(), Status.READY.name()));
                          }
                     }
                     em.flush();
                     claimList.refresh();
                     
                     facesMessages.add(Severity.INFO, "successfully sent " + selected.size() + " claim(s)");
                     return "success";
                }
           }
      }
      



      So when I click Send selected button, 'TransactionRequiredException: no transaction is in progress' error. What am I missing here? Is there any way to achieve what I am trying to do here? Or is there any other way to do it?


      Any suggestion and leads are appreciated. Thank you.


      Here's the partial stack trace:


      2009-06-04 10:01:16,292 SEVERE [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http-127.0.0.1-8080-2) JSF1054: (Phase ID: INVOKE_APPLICATION 5, View ID: /ClaimList.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@77587d]
      2009-06-04 10:01:16,292 WARN  [org.jboss.seam.web.ExceptionFilter] (http-127.0.0.1-8080-2) handling uncaught exception
      javax.servlet.ServletException: #{multiClaimListAction.sendSelected}: javax.persistence.TransactionRequiredException: no transaction is in progress
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:277)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
           at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
           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:45)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
           at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
           at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
           at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
           at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
           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:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
           at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
           at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
           at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
           at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
           at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
           at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
           at java.lang.Thread.run(Thread.java:595)
      Caused by: javax.faces.FacesException: #{multiClaimListAction.sendSelected}: javax.persistence.TransactionRequiredException: no transaction is in progress
           at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
           at javax.faces.component.UICommand.broadcast(UICommand.java:387)
           at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
           at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
           at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
           at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
           at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
           ... 43 more