我正在使用 EclipseLink 2.3.0。我有一个从单元测试中调用的方法(因此在容器之外,没有 JTA),如下所示:
EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
这些更改没有被持久化到数据库中,并且看了很长时间,最终意识到 EntityManager.getTransaction() 实际上返回了一个 NEW EntityTransaction,而不是两个调用中的同一个。效果是第一个调用创建一个新事务并开始它,第二个调用创建另一个事务并提交它。因为从未提交过第一个事务,所以不会保存更改。我们这样验证:
log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
这导致了这些日志消息:
INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@1e34f445
INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@706a4d1a
两个不同的对象 ID 验证存在两个不同的实例。将代码更改为:
EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();
...解决了这个问题。现在,当我运行代码时,我看到为执行数据库工作而生成的 SQL 语句,并且查看数据库,数据已更改。
我对这个结果有点惊讶,因为我在网上看到了很多代码示例(一般针对 JPA,特别针对 EclipseLink),这些示例推荐了我们用于管理事务的代码。我专门搜索了有关此的信息,但没有找到任何信息。发生什么了?
我在 JPA 规范中查找了确切指定 getTransaction() 功能的内容,并且没有具体说明事务是新的还是相同的。persistence.xml 中是否有控制此设置的设置?行为是否特定于 JPA 规范的每个实现?
非常感谢您提供任何信息或指导。