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.
source to share
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:
- You either use the RESOURCE_LOCAL datasource and expose it via JNDI
- You save the JTA datasource and configure Hibernate to use Spring JtaTransactionManager with the actual Arjuna Transaction Manager
source to share