JPA/EclipseLink:EntityManager.getTransaction()是创建新事务还是返回活动事务?

Unc*_*air 13 jpa transactions eclipselink

我正在使用EclipseLink 2.3.0.我有一个方法,我从单元测试(因此在容器之外,没有JTA)调用,看起来像这样:

EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
Run Code Online (Sandbox Code Playgroud)

这些更改没有被持久化到数据库,并且查看了很长时间,最后意识到EntityManager.getTransaction()实际上返回了一个新的EntityTransaction,而不是两个调用中的同一个.结果是第一次调用创建一个新事务并开始它,第二次调用创建另一个事务并提交它.由于第一个事务从未提交,因此不会保存更改.我们这样验证了这个:

log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
Run Code Online (Sandbox Code Playgroud)

这导致了这些日志消息:

INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@1e34f445
INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@706a4d1a
Run Code Online (Sandbox Code Playgroud)

两个不同的对象ID验证有两个不同的实例.将代码更改为:

EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();
Run Code Online (Sandbox Code Playgroud)

......纠正了这个问题.现在,当我运行代码时,我看到生成的SQL语句用于执行数据库工作,并查看数据库中的数据已更改.

我对这个结果感到有些惊讶,因为我在网上看到了很多代码示例(通常用于JPA,特别是用于EclipseLink),它们推荐了我们用于管理事务的代码.我搜索了很多关于此的信息,但没有找到任何东西.发生什么了?

我在JPA规范中查找了具体指定getTransaction()的功能,如果事务是新的或相同的话,它并不具体.persistence.xml中是否有一个设置来控制它?该行为是否特定于JPA规范的每个实现?

非常感谢任何信息或指导.

Jam*_*mes 5

使用getTransaction()可以在JPA和EclipseLink中工作(这是我们自己的测试工作方式).

我的猜测是你做的其他事情很奇怪.

你在使用Spring还是其他层?请包含测试的完整代码和persistence.xml.确保您没有在persistence.xml中使用JTA.


JB *_*zet 1

JPA 规范(参见第 7.5.4 段)有明确的示例,显示如何使用 来getTransaction()开始和提交事务。所以你的代码应该没问题。

您的测试显示您获得了两个不同的对象,但这并不意味着不使用相同的事务。也许返回的对象只是单个真实事务对象的代理。

或者事务可能是在隐藏在// make some changes.