【发布时间】:2017-02-01 09:48:10
【问题描述】:
我正在尝试使用一个 EntityManager 打开事务两次:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("HelloWorldPU");
EntityManager em = emf.createEntityManager();
Message message0 = new Message();
message0.setText("Hi!!");
em.getTransaction().begin();
em.persist(message0);
em.getTransaction().commit();
em.close();
Message message1 = new Message();
message1.setText("Bye!!");
System.out.println("i'm here");
em.getTransaction().begin();
em.persist(message1);
em.getTransaction().commit();
em.close();
并得到一个异常:
我来了
线程“main”java.lang.IllegalStateException 中的异常:org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@31e4bb20 已关闭
我的猜测是:不可能从已关闭的 EntityManager 中获得另一笔交易。然而JPA Spec 说:
EntityManager.close方法关闭实体管理器以释放其持久性上下文和其他资源。调用close后,应用程序不得在EntityManager实例上调用除getTransaction和isOpen之外的任何其他方法,否则将抛出IllegalStateException。如果在事务处于活动状态时调用close方法,则持久性上下文将保持受管理状态,直到事务完成。
谁能解释我错在哪里?调用getTransaction 的可能性不意味着我可以使用这个事务并调用事务的方法吗?
谢谢。
更新
感谢您的回答,这些对我最有帮助:
1:
在调用 close 之前,您可以使用 EntityManager,是的。没有 “重新打开”方法。创建 EntityManager 是一项廉价的操作——尼尔 斯托克顿 13 分钟前
2:
您可以调用 getTransaction 来检查事务是否处于活动状态。于 还可以关闭具有活动 tx 的 EntityManager(如文档 状态)并在关闭后提交)。因此,您可以致电 获取交易。 – M. Deinum 9 分钟前
【问题讨论】:
-
文档很清楚.... 应用程序不能在 EntityManager 实例上调用任何其他方法,除了 getTransaction 和 isOpen,...您正在尝试坚持不允许使用封闭实体管理器的东西。您应该只在实体管理器上调用一次 close。
-
好的,但我无法理解的是为什么我可以调用 getTransaction 然后不能使用它?
-
你为什么要关闭 EntityManager 然后尝试调用它的任何方法?!更不用说稍后再尝试关闭它!
-
所以这意味着我只能使用一次创建的EntityManager,并且在close()方法之后它不再可用,尽管有可能再次getTransaction,对吧?只是想正确理解这个概念。
-
您可以使用 EntityManager 直到您调用 close,是的。没有“重新打开”的方法。创建 EntityManager 是一种廉价的操作