8 Replies Latest reply on Dec 19, 2007 6:20 PM by pmuir

    Scope of EntityManager

    dapeng

      What is the default scope of a jpa entity manager in Seam? My experience is that it is CONVERSATION. Is that correct?

      I often get an error message on the console that the transaction can not be started, when I access a page, which contains no component reference in the cnversation scope. The reason is somehow the component lookup for entityManager in default scope (CONVERSATION) fails, because no conversation has started yet. As soon as a conversation has been started in my application, the exception disappears.

      java.lang.IllegalStateException: Could not start transaction
       at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:571
      )
       at org.jboss.seam.jsf.SeamPhaseListener.handleTransactionsBeforePhase(Se
      amPhaseListener.java:307)
       at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseList
      ener.java:142)
       at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.ja
      va:116)
       at org.ajax4jsf.resource.ResourceLifecycle.invokePhaseListener(ResourceL
      ifecycle.java:201)
       at org.ajax4jsf.resource.ResourceLifecycle.processPhaseListeners(Resourc
      eLifecycle.java:177)
       at org.ajax4jsf.resource.ResourceLifecycle.send(ResourceLifecycle.java:1
      47)
       at org.ajax4jsf.resource.InternetResourceService.load(InternetResourceSe
      rvice.java:336)
       at org.ajax4jsf.cache.LRUMapCache.load(LRUMapCache.java:116)
       at org.ajax4jsf.cache.LRUMapCache.get(LRUMapCache.java:87)
       at org.ajax4jsf.resource.InternetResourceService.serviceResource(Interne
      tResourceService.java:198)
       at org.ajax4jsf.resource.InternetResourceService.serviceResource(Interne
      tResourceService.java:144)
       at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:265)
       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.web.LoggingFilter.doFilter(LoggingFilter.java:58)
       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(Appl
      icationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
      ilterChain.java:206)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFi
      lter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
      icationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
      ilterChain.java:206)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
      alve.java:230)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
      alve.java:175)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(Securit
      yAssociationValve.java:179)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValv
      e.java:84)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
      ava:127)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
      ava:102)
       at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedC
      onnectionValve.java:157)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
      ve.java:109)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
      a:262)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
      :844)
       at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
      ss(Http11Protocol.java:583)
       at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:44
      6)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: org.springframework.transaction.CannotCreateTransactionException: Cou
      ld not open JPA EntityManager for transaction; nested exception is java.lang.Ill
      egalArgumentException: Instance must not be null
       at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransact
      ionManager.java:374)
       at org.springframework.transaction.support.AbstractPlatformTransactionMa
      nager.getTransaction(AbstractPlatformTransactionManager.java:350)
       at org.jboss.seam.ioc.spring.SpringTransaction.begin(SpringTransaction.j
      ava:74)
       at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:566
      )
       ... 35 more
      Caused by: java.lang.IllegalArgumentException: Instance must not be null
       at org.springframework.util.Assert.notNull(Assert.java:112)
       at org.springframework.util.ClassUtils.getAllInterfaces(ClassUtils.java:
      703)
       at org.jboss.seam.ioc.spring.SeamManagedEntityManagerFactory.createEntit
      yManager(SeamManagedEntityManagerFactory.java:61)
       at org.springframework.orm.jpa.JpaTransactionManager.createEntityManager
      ForTransaction(JpaTransactionManager.java:391)
       at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransact
      ionManager.java:315)
       ... 38 more
      12:02:31,191 ERROR [SeamPhaseListener] swallowing exception
      java.lang.IllegalStateException: Could not start transaction
       at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:571
      )
       at org.jboss.seam.jsf.SeamPhaseListener.handleTransactionsBeforePhase(Se
      amPhaseListener.java:307)
       at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseList
      ener.java:142)
       at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.ja
      va:116)
       at org.ajax4jsf.resource.ResourceLifecycle.invokePhaseListener(ResourceL
      ifecycle.java:201)
       at org.ajax4jsf.resource.ResourceLifecycle.processPhaseListeners(Resourc
      eLifecycle.java:177)
       at org.ajax4jsf.resource.ResourceLifecycle.send(ResourceLifecycle.java:1
      47)
       at org.ajax4jsf.resource.InternetResourceService.load(InternetResourceSe
      rvice.java:336)
       at org.ajax4jsf.cache.LRUMapCache.load(LRUMapCache.java:116)
       at org.ajax4jsf.cache.LRUMapCache.get(LRUMapCache.java:87)
       at org.ajax4jsf.resource.InternetResourceService.serviceResource(Interne
      tResourceService.java:198)
       at org.ajax4jsf.resource.InternetResourceService.serviceResource(Interne
      tResourceService.java:144)
       at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:265)
       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.web.LoggingFilter.doFilter(LoggingFilter.java:58)
       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(Appl
      icationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
      ilterChain.java:206)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFi
      lter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
      icationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
      ilterChain.java:206)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
      alve.java:230)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
      alve.java:175)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(Securit
      yAssociationValve.java:179)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValv
      e.java:84)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
      ava:127)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
      ava:102)
       at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedC
      onnectionValve.java:157)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
      ve.java:109)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
      a:262)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
      :844)
       at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
      ss(Http11Protocol.java:583)
       at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:44
      6)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: org.springframework.transaction.CannotCreateTransactionException: Cou
      ld not open JPA EntityManager for transaction; nested exception is java.lang.Ill
      egalArgumentException: Instance must not be null
       at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransact
      ionManager.java:374)
       at org.springframework.transaction.support.AbstractPlatformTransactionMa
      nager.getTransaction(AbstractPlatformTransactionManager.java:350)
       at org.jboss.seam.ioc.spring.SpringTransaction.begin(SpringTransaction.j
      ava:74)
       at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:566
      )
       ... 35 more
      Caused by: java.lang.IllegalArgumentException: Instance must not be null
       at org.springframework.util.Assert.notNull(Assert.java:112)
       at org.springframework.util.ClassUtils.getAllInterfaces(ClassUtils.java:
      703)
       at org.jboss.seam.ioc.spring.SeamManagedEntityManagerFactory.createEntit
      yManager(SeamManagedEntityManagerFactory.java:61)
       at org.springframework.orm.jpa.JpaTransactionManager.createEntityManager
      ForTransaction(JpaTransactionManager.java:391)
       at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransact
      ionManager.java:315)
       ... 38 more


      I am using Seam together with Spring. application-context.xml

      <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <!-- <property name="dataSource" ref="dataSource"/> -->
       <property name="persistenceUnitName" value="asap"/>
       </bean>
      
       <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <!-- Be sure to specify the SeamManagedEntityManagerFactory since that will manage the EM that will be
       beginning and ending transactions.-->
       <property name="entityManagerFactory" ref="seamEntityManagerFactory" />
       </bean>
      
       <tx:annotation-driven proxy-target-class="true" />
      
       <seam:configure-scopes />
       <bean
       class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
       <!-- Because we have multiple EntityManagerFactories in this applicaitonContext identify the
       SeamManagedEntityManagerFactory as the default -->
       <property name="defaultPersistenceUnitName" value="persistenceContextName" />
       </bean>
      
       <!-- EMF that wraps a Seam Managed EM instance for use in Spring -->
       <bean id="seamEntityManagerFactory" class="org.jboss.seam.ioc.spring.SeamManagedEntityManagerFactoryBean">
       <!-- The Seam managed-persistence-context component name. -->
       <property name="persistenceContextName" value="entityManager" />
       <!-- Optionally provide a unit name. If not specified the default would be the persistenceContextName -->
       <property name="persistenceUnitName" value="persistenceContextName" />
       </bean>


      components.xml

      <core:init debug="true" />
      
       <core:manager conversation-timeout="120000"
       concurrent-request-timeout="500" conversation-id-parameter="cid" />
      
       <persistence:managed-persistence-context name="entityManager"
       auto-create="true" entity-manager-factory="#{entityManagerFactory}" />
      
      
       <spring:context-loader>
       <spring:config-locations>
       <value>classpath:/META-INF/web-context.xml</value>
       <value>classpath:/META-INF/core-custom-context.xml</value>
       <value>classpath:/META-INF/application-context.xml</value>
       </spring:config-locations>
       </spring:context-loader>
      
       <spring:spring-transaction
       platform-transaction-manager="#{transactionManager}" />
      


        • 1. Re: Scope of EntityManager
          youngm

          What do you mean "when I access a page, which contains no component reference in the conversation scope"? The way your have everything configured Seam should never be attempting to create a transaction before a conversation is created.

          Can you describe more what you're doing to get Seam in this state?

          Mike

          • 2. Re: Scope of EntityManager
            dapeng

             

            The way your have everything configured Seam should never be attempting to create a transaction before a conversation is created.


            Can you elaborate on this statement. I already posted my configuration. I enabled the seam transaction management and using a layered architecture a spring-based application layer. The entry point into my application is for example a list page, which uses a query to show a list of results. The action executing the query has a page scope, because I don't need to start any conversation at that timepoint.

            According to my understanding, a non-longrunning should be started upon every request. The error I get is not reproducable. But once I was able to cathc it in my debug session. There I got a null entity manager in the line 59 o f the class SeamManagedEntityManagerFactory.
            EntityManager em = (EntityManager) component.getInstance(persistenceContextName);


            The only explanation I have is that somehow the conversation context is not yet activated at that time, so the line 1865 in the class Component is not executed.

            result = component.newInstance();


            But why sometimes the conversation is not activated for an incoming request, is not clear for me. It seems the conversation context will only be activated after the restore view phase in the seamphase listener. Could there be some cases, where only the render view phase is invoked without the restore view phase, so that conversation context was no initialized?

            Any hint will be appreciated.

            • 3. Re: Scope of EntityManager
              dapeng

              Hi,


              I think I've found the reason for this problem. I think it is a bug in combination with richfaces. The error occurd when serving a request for

              /mywebapp/a4j_3_1_1-SNAPSHOTorg/richfaces/renderkit/html/css/modalPanel.xcss/DATB/eAGLZKr5DAADWQHL

              which is a resource for a richfaces component.

              As you can see in the stack trace below, this request somehow triggerd the JSF lifecycle, which causes the SeamPhaseListener to run, which again tries to initialize the entity manager, though the conversation context has not been activated yet.

              SeamManagedEntityManagerFactory.createEntityManager() line: 59
              JpaTransactionManager.createEntityManagerForTransaction() line: 391
              JpaTransactionManager.doBegin(Object, TransactionDefinition) line: 315
              JpaTransactionManager(AbstractPlatformTransactionManager).getTransaction(TransactionDefinition) line: 350
              SpringTransaction.begin() line: 74
              SeamPhaseListener.begin(PhaseId) line: 566
              SeamPhaseListener.handleTransactionsBeforePhase(PhaseEvent) line: 307
              SeamPhaseListener.beforeServletPhase(PhaseEvent) line: 142
              SeamPhaseListener.beforePhase(PhaseEvent) line: 116
              ResourceLifecycle.invokePhaseListener(PhaseListener, PhaseEvent, boolean) line: 201
              ResourceLifecycle.processPhaseListeners(PhaseListener[], PhaseEvent, boolean) line: 177
              ResourceLifecycle.send(ResourceContext, InternetResource) line: 147
              InternetResourceService.load(Object, Object) line: 336
              LRUMapCache.load(Object, Object) line: 116
              LRUMapCache.get(Object, Object) line: 87
              InternetResourceService.serviceResource(String, HttpServletRequest, HttpServletResponse) line: 198
              InternetResourceService.serviceResource(HttpServletRequest, HttpServletResponse) line: 144
              Filter(BaseFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 265
              Ajax4jsfFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 60
              SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69
              LoggingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 58
              SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69
              SeamFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 158
              


              Any comment?

              • 4. Re: Scope of EntityManager
                youngm

                So can you consistently get the error hitting that richfaces url? The strange thing is that if it's hitting the SeamPhaseListener then it should be creating a conversation.

                What it sounds like is the transaction is getting started before the conversation is started. However, the Seam transaction abstraction is supposed to take that into account. If you'll notice there is an attribute on spring:transaction that says if this transaction requires a conversation context or not. By default this is set to true so you should be fine. Could you try debugging through the SeamPhaseListener to see if it really is trying to start a transaction before the conversation is created?

                Mike

                • 5. Re: Scope of EntityManager
                  youngm

                  Put a breakpoint in SeamPhaseListener.handleTransactionsBeforePhase and see if you can determine why beginTran is being set to true in the case where you get this error. If the phase id is RenderResponse or ApplyRequestValues and a conversation does not exist then we can dig further from there.

                  Mike

                  • 6. Re: Scope of EntityManager
                    dapeng

                    Hi,

                    I found the problem and it is a bug in the ajax4jsf in the class org.ajax4jsf.resource.ResourceLifecycle. There in the method processPhaseListeners all PhaseListener except the first 1 will be notified about the "after phase". The loop end condition should definitely be i >= 0. Under this condition the first listener, which is the SeamPhaseListener will not be notified.

                    private void processPhaseListeners(PhaseListener[] phaseListeners,
                    PhaseEvent phaseEvent, boolean beforePhase) {
                    if (beforePhase) {
                    // Invoke before phase listeners
                    for (int i = 0; i < phaseListeners.length; i++) {
                    PhaseListener phaseListener = phaseListeners;
                    invokePhaseListener(phaseListener, phaseEvent, beforePhase);
                    }

                    } else {
                    // Invoke after phase listeners, in reverse order.
                    for (int i = phaseListeners.length - 1; i > 0; i--) {
                    PhaseListener phaseListener = phaseListeners
                    ;
                    invokePhaseListener(phaseListener, phaseEvent, beforePhase);
                    }

                    }
                    }


                    • 7. Re: Scope of EntityManager
                      youngm

                      Interesting, out of curiosity what version of a4j is this? Is this the latest RichFaces?

                      • 8. Re: Scope of EntityManager
                        pmuir

                        We fixed this for RichFaces 3.1.2.GA and later IIRC. 3.1.3 is definitely ok :)