5 Replies Latest reply on Apr 4, 2007 9:32 AM by pmuir

    Possible bug - POJO doesn't automatically join transaction

      Environment: Tomcat 5.5 + Seam 2.1.0 + Microcontainer, Seam-managed transactions and PCs.

      UserBean.java - displays a list of existing User records, allowing user to select one (a-la "clickable lists" example) and edit it, or to create a new record:

      @Name ("userBean")
      @Scope (ScopeType.CONVERSATION)
      @Transactional
      public class UserBean extends EntityController {
       @DataModelSelection
       @Out (required = false)
       private User selectedUser;
       @DataModel
       private List<User> users;
      
       public void addUser() {
       selectedUser = new User();
       }
       public void cancelEdit() {
       selectedUser = null;
       }
       @Factory ("users")
       @Begin (flushMode = FlushModeType.MANUAL)
       public void createRecords() {
       users = createQuery("SELECT u FROM User u").getResultList();
       }
       public void saveUser() {
       // getEntityManager().joinTransaction();
       persist(selectedUser);
       flush();
       addFacesMessage("User #{selectedUser.username} succesfully saved");
       createRecords();
       }
       public void selectUser() {
       }
      }
      


      When executing saveUser(), if selectedUser is a transient (new) instance, the flush() call throws a "javax.persistence.TransactionRequiredException: no transaction is in progress". If the first line is uncommented, the save completes successfully (verified in DB). When selectedUser is a managed (existing) instance, the updates complete successfully whether the first line is commented or not.

      Is this a bug? Am I using the bean in a correct way?

      Thanks,

      Alex

        • 1. Re: Possible bug - POJO doesn't automatically join transacti
          pmuir

          n.b. EntityHome.persist calls getEntityManager.joinTransaction();

          It's working correctly for me anyway.

          Post all the exceptions in the error log

          • 2. Re: Possible bug - POJO doesn't automatically join transacti

            EntityHome.persist might call joinTransaction, but EntityController.persist (which I use) certainly does not. Anyway, here's the stack trace:

            ERROR [org.jboss.seam.web.ExceptionFilter] - uncaught exception
            javax.servlet.ServletException: Error calling action method of component with id _id2:_id58
             at javax.faces.webapp.FacesServlet.service(FacesServlet.java:154)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:63)
             at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
             at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
             at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:79)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
             at org.jboss.seam.web.SeamFilter.doFilter(SeamFilter.java:84)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
             at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
             at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
             at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
             at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
             at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
             at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
             at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
             at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
             at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
             at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
             at java.lang.Thread.run(Thread.java:595)
            ERROR [org.jboss.seam.web.ExceptionFilter] - exception root cause
            javax.faces.FacesException: Error calling action method of component with id _id2:_id58
             at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:72)
             at javax.faces.component.UICommand.broadcast(UICommand.java:109)
             at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
             at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
             at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
             at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
             at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
             at javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:63)
             at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
             at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
             at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:79)
             at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
             at org.jboss.seam.web.SeamFilter.doFilter(SeamFilter.java:84)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
             at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
             at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
             at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
             at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
             at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
             at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
             at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
             at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
             at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
             at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
             at java.lang.Thread.run(Thread.java:595)
            Caused by: javax.faces.el.EvaluationException: /users.xhtml @42,67 action="#{userBean.saveUser}": javax.persistence.TransactionRequiredException: no transaction is in progress
             at com.sun.facelets.el.LegacyMethodBinding.invoke(LegacyMethodBinding.java:73)
             at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:61)
             ... 31 more
            Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
             at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:294)
             at org.jboss.seam.persistence.EntityManagerProxy.flush(EntityManagerProxy.java:81)
             at org.jboss.seam.framework.EntityController.flush(EntityController.java:52)
             at test.UserBean.saveUser(UserBean.java:46)
             at test.UserBean$$FastClassByCGLIB$$48b4ac17.invoke(<generated>)
             at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
             at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:45)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:57)
             at org.jboss.seam.interceptors.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:47)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
             at org.jboss.seam.interceptors.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:37)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
             at org.jboss.seam.interceptors.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:34)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
             at org.jboss.seam.interceptors.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:63)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
             at org.jboss.seam.interceptors.TransactionInterceptor$1.work(TransactionInterceptor.java:32)
             at org.jboss.seam.util.Work.workInTransaction(Work.java:37)
             at org.jboss.seam.interceptors.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:27)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
             at org.jboss.seam.interceptors.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:27)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:103)
             at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:154)
             at org.jboss.seam.intercept.JavaBeanInterceptor.intercept(JavaBeanInterceptor.java:89)
             at test.UserBean$$EnhancerByCGLIB$$5c21fbad.saveUser(<generated>)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at com.sun.el.parser.AstValue.invoke(AstValue.java:130)
             at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
             at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
             at com.sun.facelets.el.LegacyMethodBinding.invoke(LegacyMethodBinding.java:69)
             ... 32 more
            


            One thing I noticed is that if I remove the @Out annotation on selectedUser, and instead provide a getter for it (referencing it as userBean.selectedUser in the page), the exception doesn't happen.

            • 3. Re: Possible bug - POJO doesn't automatically join transacti
              pmuir

              Ok, sorry, I didn't read your post carefully enough.

              If you are using a Seam JavaBean component, then you aren't running in a managed environment (apart from what @Transactional gives you [1]), so it's your job to call joinTransaction() as the conversation scoped EntityManager may have been created outside this transaction - at least that is my understanding.

              [1]

              ie. method invocations should take place in a transaction, and if no transaction exists when the method is called, a transaction will be started just for that method


              • 4. Re: Possible bug - POJO doesn't automatically join transacti

                Ok, thanks for the clarification. So, as I understand it, managed transactions give me a transaction around the method, and managed PCs give me an injected EM - but this doesn't mean that the EM automatically joins the transaction? Searched the reference docs, but haven't found any mention on whether it works one way or the other...

                Still, the fact that it only breaks for transient entities and not for managed ones, is hard to explain (for me, anyway). Also, it only breaks when the @Out annotation is present, which makes it even more strange.

                • 5. Re: Possible bug - POJO doesn't automatically join transacti
                  pmuir

                  Take a look at http://www.hibernate.org/hib_docs/entitymanager/reference/en/html/transactions.html#d0e1841 - I doubt it's to do with whether the entity is managed or not, but to do with the transaction/em lifecycle up to that point. But I'm not an expert.