使用JUnit4进行测试时,Spring @transactional不会启动事务
我有以下配置。
org.hibernate.dialect.SQLServerDialect true true org.hibernate.dialect.SQLServerDialect false false true true
然后,当我运行带有insert语句的测试时,它们会产生错误消息:
javax.persistence.TransactionRequiredException: Executing an update/delete query at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:47)
经过深思熟虑,我试过这个:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:services.xml" }) @Transactional(propagation = Propagation.REQUIRED) @TransactionConfiguration(defaultRollback = true) @TestExecutionListeners(value = { DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class}) public class SimpleUnitTest { @Test public void simpleTest() throws Exception { System.out.println(entityManager.getTransaction().isActive()); assertTrue(entityManager.getTransaction().isActive()); } }
它失败了。 entityManager.getTransaction()。isActive()实际上是假的。
为什么Transactional测试不会开始交易?
你需要添加
@TestExecutionListeners(TransactionalTestExecutionListener.class)
或延伸
AbstractTransactionalJUnit4SpringContextTests
获得交易行为。 (记住,您的测试类不是bean,因此常规事务配置不适用)
如果使用SpringJUnit4ClassRunner
,则默认情况下启用TransactionalTestExecutionListener
。
您需要确保在Test上下文配置中包含事务管理配置:
@ContextConfiguration(locations = { "classpath:services.xml" })
所以你可以通过注入TM bean来检查它:
@Autowired private PlatformTransactionManager transactionManager;
如果未解析依赖关系,则事务配置未正确定位。
在调试测试期间,检查堆栈跟踪中的TransactionInterceptor
。
因为您有两个与配置相关的答案,我认为问题不是配置,而是问题如何检查事务是否处于活动状态,以及如何获取该EntityManager
实例。
可能的问题可能是:使用EntityManagerFactory.createEntityManager()
方法而不是获取注入的EntityManager
。
- H2数据库在内存中 – 通过Spring / Hibernate的Init模式
- 如何在Oracle下处理大型事务?
- 调用entityManager.getTransaction()时的EJBException
- 使用Spring 3,maven,JPA,c3p0在hibernate中“java.lang.NoSuchFieldError:NONE”
- 删除不使用JpaRepository
- Struts 2和Hibernate中的exception处理
- 如何在JSF + Spring + Hibernate中使用DTO
- JTASessionContext与JDBCTransactionFactory一起使用; 使用getCurrentSession()自动刷新将无法正常运行
- 为什么Hibernate没有为MySQL创建数据库?