Hibernate5.3集成Spring5.0.6时事务获取失败问题排查
问题分析与解决方案
你遇到的TransactionRequiredException核心原因是:你手动从EntityManagerFactory创建的EntityManager并没有加入到Spring测试框架通过@Transactional开启的事务中。
Spring的@Transactional注解会自动管理它注入的EntityManager的事务上下文,但你在beforeAll里自己创建的EntityManager是独立于这个事务之外的,所以当你调用persist和flush时,它找不到可用的事务,就抛出了异常。
修复方案:直接注入EntityManager
最简单的解决方式是让Spring直接帮你注入EntityManager,而不是手动创建。修改你的测试代码如下:
@Transactional @TestInstance(TestInstance.Lifecycle.PER_CLASS) @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = Application.class) class UserTest { // 直接注入Spring管理的EntityManager @Autowired private EntityManager entityManager; @BeforeAll void beforeAll() { assertNotNull(entityManager); } @Rollback(value = false) @Test void persist() { User user = new User("testName", "password"); entityManager.persist(user); entityManager.flush(); } }
为什么这样能解决问题?
当你通过@Autowired注入EntityManager时,Spring会给你一个代理对象,这个代理会自动关联到当前由@Transactional开启的事务中。当你调用persist方法时,它会自动使用Spring管理的事务上下文,不再需要手动处理事务绑定。
另外,你也可以保留EntityManagerFactory,但需要手动将创建的EntityManager加入到当前事务中,但这种方式没必要,直接注入EntityManager是Spring推荐的最佳实践。
额外的小建议
- 你的
HibernateConfig配置是没问题的,LocalContainerEntityManagerFactoryBean和JpaTransactionManager的配置都正确,不需要修改。 - 如果你的测试方法不需要保留测试数据,可以去掉
@Rollback(false)注解,Spring默认会回滚测试事务,避免测试数据污染数据库。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

