3 Replies Latest reply on Nov 19, 2009 1:29 AM by marcio.dantas

    Seam-Spring integration transaction problems

      Hi,


      I´m currently developing an application using:




      • Seam 2.2.0GA

      • Spring 2.5.6

      • Richfaces 3.3.2SR1

      • Trinidad 1.2.12

      • HibernateEntityManager 3.4.0GA

      • Hibernate Core 3.3.2GA



      Somehow Spring and Seam is not playing well together although we configured the integration exactly as described in Dan Allens article.


      components.xml


      <persistence:managed-persistence-context name="entityManager"
                                            auto-create="true" 
                                            entity-manager-factory="#{entityManagerFactorySpring}"
                                            scope="SESSION"  />
           
          <core:init jndiPattern="#{ejbName}/local" debug="true" transaction-management-enabled="true"/>
      
          <spring:context-loader />
          <component name="threadPoolDispatcher" class="org.jboss.seam.async.ThreadPoolDispatcher" />
          
          <!-- Install the SpringDispatcher as default -->
          <spring:spring-task-executor-dispatcher schedule-dispatcher="#{threadPoolDispatcher}" task-executor="#{springThreadPoolTaskExecutor}"/>
          
          <spring:spring-transaction platform-transaction-manager="#{transactionManager}" join-transaction="true"  />



      applications-context.xml


      <bean id="entityManagerFactorySpring" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                      <property name="dataSource" ref="dataSource"/>
                      <property name="persistenceUnitName" value="easyClubDatabasePU"/>
                      <!-- Use alternate location to prevent JBoss AS from automatically loading persistence units (in-container) -->
                      <property name="persistenceXmlLocation" value="classpath:META-INF/persistence-spring.xml"/>
              <property name="jpaDialect">
                  <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
              </property>
              <property name="jpaVendorAdapter">
                  <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
                      <property name="showSql" value="false"/>
                      <property name="generateDdl" value="true"/>
                  </bean>
              </property>
              </bean>
      
              <!-- This example uses resource local JpaTransactionManager.  You could just as easily use a JtaTransactionManager -->
              <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="entityManagerFactory"/>
              </bean>
      
              <tx:annotation-driven proxy-target-class="true" />
      
              <seam:configure-scopes default-auto-create="true" />
      
              <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="easyClubDatabasePU:extended"/>
              </bean>
      
              <!-- EMF that wraps a Seam Managed EM instance for use in Spring -->
              <bean id="entityManagerFactory" 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="easyClubDatabasePU:extended"/>
              </bean>



      When debbugging into the transactions, the Spring TX begins and commits every request. So does the Seam-TX. But some exceptions occur when Seam tries to open it´s transaction:


      16:29:43,640 INFO  [STDOUT] 16:29:43,640 ERROR Exceptions:86  - handled and logged exception
      java.lang.IllegalStateException: Could not start transaction
              at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:598)
              at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:583)
              at org.jboss.seam.jsf.SeamPhaseListener.handleTransactionsBeforePhase(SeamPhaseListener.java:327)
              at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseListener.java:144)
              at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:118)
              at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:214)
              at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:96)
              at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:247)
              at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:157)
              at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
              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:178)
              at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
              at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
              at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
              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:60)
              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.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:619)
      Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException:
      Transaction already active
              at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:375)
              at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:374)
              at org.jboss.seam.ioc.spring.SpringTransaction.begin(SpringTransaction.java:67)
              at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:593)
              ... 55 more
      Caused by: java.lang.IllegalStateException: Transaction already active
              at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:35)
              at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:70)
              at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:330)
              ... 58 more



      No it´s hard to understand why these exception occures as there are not many reported errors with this Seam/Spring configuration. Are there any misconfigurations or things I forgot in my configuration or what could be the reason for this?


      Anyone with some help regarding this topic?


      Marco

        • 1. Re: Seam-Spring integration transaction problems
          Hi guys,

          here comes an update, which caused this problem.

          We used a rich:dropDownMenu with a menuItem without defining an explicit submitMode. The default for the menuItem is submitMode=server, which caused a form submit resulting in a new second thread. This 2nd thread got into trouble with the "regular" thread, which already opened a transaction and raised the exception.

          Actually I´m not sure if this is meant to be this way. Either that a 2nd thread will be created or that this causes the second thread to struggle with the same transaction. This is probably not specific to Spring, but this is where we found this behaviour.

          Maybe someone can drop a line about this, but setting submitMode=none finally resolved our problem.

          Marco
          • 2. Re: Seam-Spring integration transaction problems

            Have you tried solving this problem by using richfaces global queue and/or the ConfigurableSynchronizationInterceptor with a big timeout value ?


            IMO they should prevent the 2 threads from causing this transactional conflict because they prevent simultaneous request processing...

            • 3. Re: Seam-Spring integration transaction problems
              marcio.dantas

              Marco,


              I've recently integrated a jsf+spring+hibernate application with seam.


              If that is your case and you are using transactions design strategy as recommended in Java Transaction Design Strategies, one thing you must take care with is that transactional methods with propagation REQUIRED will NOT be commited at the end of the method execution as before seam. Your transaction will be commited only AFTER invoke application phase, that is, after all logic in your action or action listener has been executed.


              If you're holding locks in the database during the transactions, that could probably be a problem and you should revise you transactions design strategy and the seam transactions management.


              best regards