我不太明白为什么您要使服务方法变得如此不必要地复杂。您应该只可以这样做
@Transactionalpublic void insertUser(User user) { entityManager.persist( user );}如果有些地方需要访问本机Hibernate
Session,则可以
Session像下面这样直接打开并直接使用:
@Transactionalpublic void doSomethingFancyWithASession() { Session session = entityManager.unwrap( Session.class ); // use session as needed}这里的概念是,Spring
EntityManager通过使用
@PersistenceContext注释为您提供了一个已经起作用的实例。该实例将在您的spring
bean正在其中执行的当前线程中安全地使用。
其次,通过使用
@Transactional,这将导致Spring的事务管理自动确保
EntityManager绑定到事务,无论是事务
RESOURCE_LOCAL还是
JTA事务都基于您的环境配置。
由于调用,您遇到了问题
#getCurrentSession()。
发生的事情是Spring
EntityManager调用时创建了,然后在您的方法内部
#getCurrentSession(),您要让Hibernate创建第二个会话,该会话未绑定到由
@Transactional注释启动的事务。简而言之,它基本上类似于以下内容:
EntityManager entityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();Session aNewSession = entityManager.unwrap( Session.class ) .getFactory() .getCurrentSession();// at this point entityManager is scoped to a transaction// aNewSession is not scoped to any transaction// this also likely uses 2 connections to the database which is a waste
因此,按照我上面提到的范例进行操作,您就不再遇到问题了。你永远不应该需要调用
#getCurrentSession()或者
#openSession()在Spring环境中,如果你正确地允许Spring来注入你的
EntityManager情况给你。



