【发布时间】:2016-08-19 00:19:02
【问题描述】:
我正在使用here 中描述的“JBoss 快速入门”教程。 它演示了在独立应用程序中使用分布式事务,包括 JPA。
我已经下载了代码,运行良好,所有测试用例都是绿色的。
它包含以下测试用例:
@Test
public void testJpa() throws Exception {
System.out.println(testEntityRepository.save(new TestEntity("test1")));
System.out.println(testEntityRepository.save(new TestEntity("test2")));
System.out.println(testEntityRepository.save(new TestEntity("test3")));
org.junit.Assert.assertEquals(3, testEntityRepository.findAll().size());
}
我想让这更有趣,通过在断言之前启动事务并将其回滚,如下所示:
@Test
public void testJpa() throws Exception {
transactionManager.begin();
System.out.println(testEntityRepository.save(new TestEntity("test1")));
System.out.println(testEntityRepository.save(new TestEntity("test2")));
System.out.println(testEntityRepository.save(new TestEntity("test3")));
transactionManager.rollback();
org.junit.Assert.assertEquals(0, testEntityRepository.findAll().size());
}
对于rollback(),我希望findAll().size() 返回0。但是它继续返回3。有什么我想念的吗?回滚 JPA 状态的能力似乎是本教程的主要目标之一?
TestEntityRepository的原码:
public class TestEntityRepository {
@Inject
EntityManager entityManager;
@Transactional
public List<TestEntity> findAll() {
assert entityManager != null;
return (List<TestEntity>) this.entityManager.createQuery("select te from TestEntity te").getResultList();
}
@Transactional
public Long save(TestEntity testEntity) {
assert entityManager != null;
if (testEntity.isTransient()) {
entityManager.persist(testEntity);
entityManager.flush();
} else {
entityManager.merge(testEntity);
entityManager.flush();
}
return testEntity.getId();
}
}
其他代码可以找到here。
【问题讨论】:
-
persist 和 merge 后有什么具体原因要刷新吗?
-
请试试这个:将 testEntityRepository.save 调用移动到 TestEntityRepository 中的一个方法并从 testJpa 调用它。
-
@Jaumzera 感谢您的建议。按照您的建议尝试,但效果相同。我猜 JPA 事务不知何故没有正确链接到 JTA 事务。奇怪的是,如果我将
@Transactional替换为@Transactional(TxType.MANDATORY)并在测试用例中省略entityManager.begin(),那么我会得到一个异常,说需要一个事务,这是正确的。 -
@Jaumzera
flush()是我在阅读其他文档以寻找解决方案时发现的——不记得在哪里或为什么。再拿出来也没用。
标签: jpa jakarta-ee entitymanager jta weld