Java 当前线程没有实际事务可用的EntityManager-无法可靠地处理';齐平';呼叫
一些背景信息:我正在尝试将一个大型项目从Hibernate 3.6.8迁移到5.2.5(包括JPA升级2.0到2.1),从Spring 3.2.3迁移到4.3.5,我面临着严重的问题。到目前为止,Spring和Hibernate的配置还没有改变,在旧版本上工作得很好,但是出现了我自己无法解决的升级问题 我得到的例外是: 我的配置如下所示: pom.xml(相关代码片段): 对于春季:Java 当前线程没有实际事务可用的EntityManager-无法可靠地处理';齐平';呼叫,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,一些背景信息:我正在尝试将一个大型项目从Hibernate 3.6.8迁移到5.2.5(包括JPA升级2.0到2.1),从Spring 3.2.3迁移到4.3.5,我面临着严重的问题。到目前为止,Spring和Hibernate的配置还没有改变,在旧版本上工作得很好,但是出现了我自己无法解决的升级问题 我得到的例外是: 我的配置如下所示: pom.xml(相关代码片段): 对于春季: <dependency> <groupId>org.springframewor
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>5.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.2.6.Final</version>
<scope>provided</scope>
</dependency>
import java.sql.SQLException;
import java.util.Set;
import javax.interceptor.Interceptors;
import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
...
@Interceptors(SpringBeanAutowiringInterceptor.class)
@Transactional(propagation = Propagation.REQUIRED)
public class DBLockingImpl implements Locking {
@Autowired
private DataSource dataSource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository(value = "persistenceContext")
public class PersistenceContextImpl
implements PersistenceContext {
/**
* Instance variable for EntityManager.
*/
@PersistenceContext
private EntityManager entityManager;
@Override
public void flushAndClear() {
entityManager.flush();
entityManager.clear();
}
}
这是调用entityManager的类(此时事务已经打开,但是在entityManager上调用flush方法时会发生异常):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>5.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.2.6.Final</version>
<scope>provided</scope>
</dependency>
import java.sql.SQLException;
import java.util.Set;
import javax.interceptor.Interceptors;
import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
...
@Interceptors(SpringBeanAutowiringInterceptor.class)
@Transactional(propagation = Propagation.REQUIRED)
public class DBLockingImpl implements Locking {
@Autowired
private DataSource dataSource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository(value = "persistenceContext")
public class PersistenceContextImpl
implements PersistenceContext {
/**
* Instance variable for EntityManager.
*/
@PersistenceContext
private EntityManager entityManager;
@Override
public void flushAndClear() {
entityManager.flush();
entityManager.clear();
}
}
有人能帮我解决这个问题吗?我不明白遗漏了什么,为什么我会得到那个例外。我得到的印象是Spring没有正确地连接到Hibernates实体管理器,这就是为什么会出现异常,因为它本身似乎是被创建的,但每当它试图持久化时,就会出现异常。毕竟,我觉得它不再工作很奇怪,尽管它在这些框架的旧版本中工作得很好。与旧版本相比,配置是否有任何重大变化?我怀疑这可能是组件扫描或包扫描的问题。我在您的spring配置文件中找不到包扫描代码。请检查或更新您的配置文件。扫描似乎正常。如果查看stacktrace,您可以看到EntityManager
代理(com.sun.Proxy.$Proxy163),并按照预期将其转发给SharedEntityManager创建者
但是,在创建SharedIdentityManager之前,它会检查是否存在事务,并且该检查失败。事务应通过@Transactional
注释创建。这是通过SpringAOP实现的,可以创建扩展DBLockingImpl的GCLIB代理,也可以创建实现锁定的JDK代理。这可以通过在方法内部设置断点并查看调用堆栈来确定方法是如何调用的
查看dblockingpimpl
我注意到您使用了SpringBeanAutowiringInterceptor
,这表明dblockingpimpl不是一个SpringBean,但您只是将SpringBean自动连接到它中。如果是这种情况,那么我认为这是您的问题,因为dblockingpimpl
将不会被AOP代理,因此@Transactional将不会被应用
尝试将dblockingpimpl
制作成Springbean。我对PersistenceContextImpl
类感到困惑,为什么要覆盖PersistenceContext注释?在Spring中,注入的EntityManager是一个代理,它与事务性和线程本地存储交互,这几乎就像不尊重事务性注释一样。我认为如果有人曾经尝试过,并且知道原因,你将非常幸运。我担心您需要进行一些调试才能解决这个问题。如果您已经在升级该项目,您就不能摆脱Maven和臃肿的XML配置,转而使用Gradle;)@KlausGroenbaek很抱歉让您感到困惑,在本例中,PersistenceContextImpl并没有覆盖PersistenceContext注释,而是一个正常的类,它被使用,并且与数据库有一些交互。感谢您提供有关Gradle的信息;)我将在将来检查Gradle,但我非常确定在这一点上从Maven到Gradle的迁移将是非常致命的…:当存在对两个不同的PersistenceContext
类的引用,并且没有一个类是完全限定的时,PersistenceContextImpl
如何编译?基于Impl类的功能,它可能应该被称为以Repository结尾的东西。