如何在Spring中创建非事务性JUnit集成测试?

时间:2015-06-25 13:48:35

标签: java spring hibernate jpa transactions

集成测试类注释为:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestConfig.class)

它不应该在事务中运行,因此标记为@Transactional但是在尝试对{{1}执行持久化,合并等操作时遇到错误}},使用EntityManager注入:

  

没有可用的事务性EntityManager

如何解决这个问题?

修改 根据评论中的要求,Spring版本为4.1.0.RELEASE,@PersistenceContext如下:

IntegrationTestConfig

1 个答案:

答案 0 :(得分:4)

如果您确定永远不会致电entityManager.flush(),请按以下方式获取PersistenceContext

@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;

为什么需要这个?当使用@PersistenceContext注释(没有任何属性)时,Spring Data JPA会发布所谓的共享EntityManager。有关详情,请参阅JavaDocs for org.springframework.orm.jpa.SharedEntityManagerCreator。此类维护一个查找表,其中EntityManager方法flushmergepersistrefreshremove需要在交易。因此,只要遇到不在事务中的方法调用,它就会失败。

注释@PersistenceContext有一个type属性,可以设置为PersistenceContextType.EXTENDEDPersistenceContextType.TRANSACTION之一,后者是默认值。因此,默认@PersistenceContext会导致SharedEntityManagerCreator查找交易,如果找不到则会挽救。

使用PersistenceContextType.EXTENDED会在获取EntityManager时绕过检查事务的需要,因此代码应该有效。

如果没有事务,仍然无法调用

flush,因为JPA提供程序要求仅在事务上下文中调用它。