繁体   English   中英

Hibernate 5.2和Spring 4.3,非JPA-javax.persistence.TransactionRequiredException:没有事务在进行中

[英]Hibernate 5.2 and Spring 4.3, Non JPA - javax.persistence.TransactionRequiredException: no transaction is in progress

从休眠5.1升级到5.2.6时,出现以下错误。 具体来说,这是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)

正如您在下面的堆栈跟踪中所看到的,spring显然已经启动了一个transaction,并且实际上正在尝试在提交事务之前触发刷新。 看来,用于同步休眠和Spring事务的代码不适用于Hibernate 5.2(看起来位于org.springframework.orm.hibernate5.SpringSessionContext.currentSession()的末尾)。 这是一个开放的错误,还是我错过了某个地方的配置?

就我而言,问题是由使用Spring的JDBC TransactionManager实现的旧配置设置引起的,而不是由Hibernate集成的合适的设置引起的。 这对于Hibernate 4.1显然是可以接受的,但对于5.2不可接受。 解决方法是将我的事务管理器bean声明更改为:

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

升级由Spring XML配置支持的旧版应用程序时,我遇到了相同的问题。

必须将以下休眠属性添加到Spring LocalSessionFactory配置中:

<prop key="hibernate.transaction.coordinator_class">jta</prop>
<prop key="hibernate.transaction.jta.platform">JBossAS</prop>

原因似乎是在Hibernate 5.2中,对于非JPA应用程序,hibernate.transaction.coordinator_class的默认值为jdbc。 这在Spring事务中不能很好地发挥作用。

我们面临着同样的问题,我发现了不同的原因。

Spring 4.3.9和Hibernate 5.2.10,具有XML配置和声明式事务。 问题被setReadOnly()放置在事务中的错误位置,它在getTransaction()之后设置

错误代码:

DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionStatus = transactionManager.getTransaction(transactionDefinition);
transactionDefinition.setReadOnly(true);  //wrongly set it will not set in transactionstatus
//DAO Call
transactionManager.commit(transactionStatus);

上述代码中的更改,以解决此问题:

DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(true);
transactionStatus = transactionManager.getTransaction(transactionDefinition);
//DAO Call
transactionManager.commit(transactionStatus);

当我们将spring-boot-dependencies软件包从1.5升级到2.0.2时,我遇到了同样的异常(这将spring 4升级到5,将hibernate 5.0升级到5.2)。

我有一个标记为@Transactional的测试用例,它在内部调用一个标记为@Transactional(propagation = Propagation.NOT_SUPPORTED)的内部方法,因为它包含一些不应包含在上游事务中的东西。 升级后开始出现以下错误,该错误在Spring 4和Hibernate 5.0组合中正常运行。

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)

通过在不需要事务的方法中添加'readOnly = true'属性来解决此问题-@Transactional (readOnly = true,propagation = Propagation.NOT_SUPPORTED) 似乎较新的版本将需要它来指示或作为对调用事务子系统的提示。 检查readOnly属性文档。

另外,请在此处检查接受的答案以获取类似说明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM