Spring Hibernate "You cannot make transactions during a managed transaction!"

After upgrading my application from JSF 1.2 to JSF 2.1, I have the following Spring Hibernate exception when trying to login:

DEBUG,[interceptor.ExceptionInterceptor][],org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: commit failed
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:472)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:392)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at myapp.aop.interceptor.MethodExceptionInterceptor.invoke(MethodExceptionInterceptor.java:21)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at myapp.aop.interceptor.SessionActivityInterceptor.invoke(SessionActivityInterceptor.java:47)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy121.endSession(Unknown Source)
    at myapp.web.action.connection.ConnectionBean.connect(ConnectionBean.java:100)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
    at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
    at myapp.web.interceptor.ExceptionInterceptor.aroundInvoke(ExceptionInterceptor.java:42)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:35)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
    at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:186)
    at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:104)
    at myapp.web.action.connection.ConnectionBean_$$_javassist_seam_2.connect(ConnectionBean_$$_javassist_seam_2.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335)
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348)
    at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
    at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
    at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:46)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
    at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:1074)
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:402)
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:225)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:105)
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
    at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:327)
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:229)
    at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
    at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    at myapp.web.filter.SessionActivityFilter.doFilter(SessionActivityFilter.java:67)
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    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.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:389)
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
    at java.lang.Thread.run(Thread.java:724)
 Caused by: org.hibernate.TransactionException: commit failed
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:185)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:468)
    ... 93 more
 Caused by: org.hibernate.TransactionException: unable to commit against JDBC connection
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:116)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:178)
    ... 94 more
 Caused by: java.sql.SQLException: You cannot commit during a managed transaction!
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:1052)
    at org.jboss.jca.adapters.jdbc.WrappedConnection.commit(WrappedConnection.java:757)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:112)
    ... 95 more

      

Here is my Spring beans configuration:

    <bean id="parentSessionFactory" abstract="true">
        <property name="dataSource">
            <ref bean="myDS" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.connection.driver_class">
                    org.h2.Driver
                </prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.use_structured_cache">true</prop>                            
            </props>
        </property>
    </bean>

    <bean id="myDS"
          class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:/myDS" />
    </bean>


    <bean id="sessionFactory" parent="parentSessionFactory"
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">   
      <property name="configLocation">
        <value>
            classpath:model/hibernate.cfg.xml
        </value>
      </property>

      <property name="hibernateProperties">
        <props merge="true">
            <prop key="hibernate.dialect">
                org.hibernate.dialect.H2Dialect
            </prop>    
        </props>        
      </property>
    </bean>

    <bean id="transactionManager"
      class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory">
        <ref bean="sessionFactory"/>
      </property>
    </bean>


    <!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!-- the transactional semantics... -->
      <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <tx:method name="get*" read-only="true" />
        <tx:method name="find*" read-only="true" />
        <tx:method name="list*" read-only="true" />
        <tx:method name="read*" read-only="true" />
        <tx:method name="save*" read-only="false" isolation="READ_COMMITTED"/>
        <tx:method name="remove*" read-only="false" isolation="READ_COMMITTED"/>
        <tx:method name="refresh*" read-only="false" isolation="READ_COMMITTED"/>
        <tx:method name="delete*" read-only="false" isolation="READ_COMMITTED"/>
        <!-- other methods use the default transaction settings (see below) -->
        <tx:method name="*" />
      </tx:attributes>
    </tx:advice>
    <tx:annotation-driven transaction-manager="transactionManager"/>

<!-- ensure that the above transactional advice runs for any execution
    of an operation defined by the *Service interface -->
    <aop:config>
        <aop:pointcut id="serviceOperation"
                      expression="execution(* services..*Service*.*(..))" />
        <aop:pointcut id="daoOperation"
                      expression="execution(* dao..*Dao.*(..))" />


        <aop:advisor advice-ref="sessionActivityInterceptor"
                     pointcut-ref="serviceOperation" />         
        <aop:advisor advice-ref="exceptionInterceptor"
                     pointcut-ref="serviceOperation" />      -->
        <aop:advisor advice-ref="txAdvice"
                     pointcut-ref="serviceOperation" />
        <aop:advisor advice-ref="txAdvice"
                     pointcut-ref="daoOperation" />      
    </aop:config>

      

Here is hibernate.cfg.xml:

<hibernate-configuration>
    <session-factory>

        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<!--        <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property> -->
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        <property name="hibernate.cache.use_query_cache">true</property>
        <property name="hibernate.cache.use_second_level_cache">true</property>


        <!-- Several mapping classes here -->
    </session-factory>
</hibernate-configuration>

      

The annotation @Transactional

is only used in one method in my application and in my unit tests, but it is not used for what concerns the login part of the application.

Examining my exception, I see code that throws an exception in BaseWrapperManagedConnection

from ironjacamar-jdbc-1.0.17

:

/**
    * JDBC commit
    * @exception SQLException Thrown if an error occurs
    */
   void jdbcCommit() throws SQLException
   {
      synchronized (stateLock)
      {
         if (inManagedTransaction)
            throw new SQLException("You cannot commit during a managed transaction!");

         if (jdbcAutoCommit)
            throw new SQLException("You cannot commit with autocommit set!");
      }
      con.commit();

      if (mcf.isJTA().booleanValue())
      {
         if (inLocalTransaction.getAndSet(false))
         {
            Collection<ConnectionEventListener> copy = null;
            synchronized (cels)
            {
               copy = new ArrayList<ConnectionEventListener>(cels);
            }

            ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);

            for (Iterator<ConnectionEventListener> i = copy.iterator(); i.hasNext();)
            {
               ConnectionEventListener cel = i.next();
               try
               {
                  cel.localTransactionCommitted(ce);
               }
               catch (Throwable t)
               {
                  if (trace)
                     getLog().trace("Error notifying of connection committed for listener: " + cel, t);
               }
            }
         }
      }
   }

      

variable inManagedTransaction

in is LocalManagedConnection

set to true, starting with ironjacamar-jdbc-1.0.17

:

/**
    * {@inheritDoc}
    */
   public void begin() throws ResourceException
   {
      lock();
      try
      {
         synchronized (stateLock)
         {
            if (!inManagedTransaction)
            {
               try
               {
                  if (underlyingAutoCommit)
                  {
                     underlyingAutoCommit = false;
                     con.setAutoCommit(false);
                  }
                  checkState();
                  inManagedTransaction = true;
               }
               catch (SQLException e)
               {
                  checkException(e);
               }
            }
            else
               throw new ResourceException("Trying to begin a nested local tx");
         }
      }
      finally
      {
         unlock();
      }
   }

      

And the only place where this value is inManagedTransaction

set to false is in the method LocalManagedConnection

commit()

or rollback()

:

/**
    * {@inheritDoc}
    */
   public void commit() throws ResourceException
   {
      lock();
      try
      {
         synchronized (stateLock)
         {
            if (inManagedTransaction)
               inManagedTransaction = false;
         }
         try
         {
            con.commit();
         }
         catch (SQLException e)
         {
            checkException(e);
         }
      }
      finally
      {
         unlock();
      }
   }

   /**
    * {@inheritDoc}
    */
   public void rollback() throws ResourceException
   {
      lock();
      try
      {
         synchronized (stateLock)
         {
            if (inManagedTransaction)
               inManagedTransaction = false;
         }
         try
         {
            con.rollback();
         }
         catch (SQLException e)
         {
            try
            {
               checkException(e);
            }
            catch (Exception e2)
            {
               // Ignore
            }
         }
      }
      finally
      {
         unlock();
      }
   }

      

Is it normal that I have two ManagedConnections one BaseWrapperManagedConnection

and the other LocalManagedConnection

and that I am looking at both commit methods?

I also read that JBoss can also deal with transactions (container-managed transactions). Is it possible that both Spring and JBoss are trying to handle my sessions and transactions?

I am using Hibernate 4.2 and Spring 3.2.0. Most of them are classic configuration, as in many tutorials on the Internet. An application using this configuration worked using JSF 1.2. Thanks for any advice, hints.

+3


source to share


2 answers


You might have configured a JSA DataSource in JBoss, which is a managed transactional resource, and then you are using non-JTA HibernateTransactionManager

.

To fix this, you have two options:



+2


source


if your datasource is using jta you shouldn't call transaction.begin, none of them emit this transaction demarcation by the container. if your datasource uses RESOURCE_LOCAL, you should delimit all transactions, even read only ones.



+1


source







All Articles