Reputation: 81
I am seeing the following error upon upgrading my application from hibernate 5.1 to 5.2.6. Specifically, this is spring 4.3.5.
javax.persistence.TransactionRequiredException: no transaction is in progress
org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3450)
org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1418)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414)
org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
com.sun.proxy.$Proxy140.mapUserFromContext(Unknown Source)
org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:87)
As you can see in the stack trace below, spring clearly has started a transaction , and is actually trying to trigger a flush before committing it's transaction. It appears that the code that syncronizes hibernate and spring transactions is not working with hibernate 5.2 (looks to be located at the end of org.springframework.orm.hibernate5.SpringSessionContext.currentSession()
). Is this an open bug, or am I missng a config somewhere?
Upvotes: 2
Views: 8310
Reputation: 551
I was facing the same exception when we upgraded our spring-boot-dependencies bundle from 1.5 to 2.0.2 (which effectively upgrades spring 4 to 5, and hibernate 5.0 to 5.2).
I had a test case that was marked @Transactional which internally invokes an internal method that was marked @Transactional(propagation=Propagation.NOT_SUPPORTED) as it had some stuff that shouldn't be a part of the upstream transaction. Started getting the below error after the upgrade which was working fine with Spring 4 and Hibernate 5.0 combination.
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:147)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:96)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:922)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:532)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
It was resolved by adding 'readOnly = true' attribute to the method where a transaction wasn't needed - @Transactional(readOnly = true, propagation=Propagation.NOT_SUPPORTED). It appears that newer versions will need this to indicate or serve as a hint to the calling transaction subsystem. Check readOnly attribute docs.
Also, do check the accepted answer here for a similar explanation.
Upvotes: 1
Reputation: 2044
I encountered the same problem when upgrading a legacy application that is backed by Spring XML configuration.
The following hibernate properties had to be added to the Spring LocalSessionFactory configuration:
<prop key="hibernate.transaction.coordinator_class">jta</prop>
<prop key="hibernate.transaction.jta.platform">JBossAS</prop>
The reason seems to be that with Hibernate 5.2 the default value for hibernate.transaction.coordinator_class is jdbc for non-JPA applications. And that doesn't play well with Spring transactions.
Upvotes: 2
Reputation: 161
We are facing the same problem, I found the different reason for it.
Spring 4.3.9 , Hibernate 5.2.10 with XML Configuration & Declarative transaction. Problem was setReadOnly() placed at wrong place in transaction, it sets after the getTransaction()
Code With error:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionStatus = transactionManager.getTransaction(transactionDefinition);
transactionDefinition.setReadOnly(true); //wrongly set it will not set in transactionstatus
//DAO Call
transactionManager.commit(transactionStatus);
Changes in above code for fixing the issue:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(true);
transactionStatus = transactionManager.getTransaction(transactionDefinition);
//DAO Call
transactionManager.commit(transactionStatus);
Upvotes: 1
Reputation: 15199
In my case, the issue was caused by an old configuration setting using Spring's JDBC TransactionManager implementation, rather than the appropriate Hibernate-integrated one. This was apparently acceptable for Hibernate 4.1, but not for 5.2. The fix was to change my transaction manager bean declaration to:
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
Upvotes: 2