【发布时间】:2017-07-04 15:16:41
【问题描述】:
我正在尝试开发一个使用 JPA 的小程序,但可以在没有应用程序服务器的情况下运行,即作为常规 Java SE 应用程序。
AFAIK,对于 JavaEE,应用程序服务器负责启动和结束数据库事务。现在我的问题是我使用 JPA 从一些内部代码中得到了这个错误:
Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
at <see below>
导致此异常的代码等价于:
String persistenceUnitName; // actually comes from some config file
EntityManager entityManager = Persistence.createEntityManagerFactory(persistenceUnitName).createEntityManager();
entityManager.flush(); // exception is thrown here
我无法更改该代码,因此它依赖于自动启动的事务。
在自定义事务中包装对上述代码的调用,如下所示:
String persistenceUnitName; // same persistence unit name
EntityManager entityManager = Persistence.createEntityManagerFactory(persistenceUnitName).createEntityManager();
entityManager.getTransaction().begin();
callAboveCode();
entityManager.getTransaction().commit();
没有帮助。对工厂的createEntityManager() 的调用每次都会返回一个新的实体管理器,我想会导致不同的持久性上下文。
有没有办法在 Java SE 应用程序中获得自动事务处理,类似于在应用程序服务器中运行 JPA?
【问题讨论】:
-
你说第二种方法中的显式事务不起作用是什么意思?您仍然看到错误吗?
-
是的,结果相同
-
绝对应该更改导致异常的代码:它依赖于自动处理的事务,就好像它在 Java EE 或 Spring 上下文中运行一样,但它使用 Persistence 类创建了一个 EntityManagerFactory,如如果它在 Java SE 上下文中运行。因此,对于这两种情况,它都是错误的。使用 Spring,并更改错误代码。
-
它实际上混合了 CDI(注入 @any 实体管理器实例,在我的情况下始终为空)和使用 Persistence 类手动创建(如果没有找到)。看起来它试图同时支持 Java EE 和 Java SE
-
如果您使用的是 RESOURCE_LOCAL 事务(JavaSE 的默认设置),那么您显然必须调用
getTransaction().begin()。我知道一个 JPA 提供程序允许非事务性持久性操作(并且您没有使用它),但不是 JPA 规范的一部分
标签: java jpa transactions jpa-2.0