本文介绍了在使用JUnit4进行测试时,Spring @transactional不启动事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有以下配置。
< beans xmlns =http://www.springframework.org/schema/ beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xmlns:tx =http://www.springframework.org/schema/tx
xsi:schemaLocation =http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd\">
< bean id =dataSourceclass =org.springframework.jdbc.datasource.IsolationLevelDataSourceAdapter>
< property name =targetDataSource>
< bean class =com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource>
< property name =uservalue =user/>
< property name =passwordvalue =password/>
< property name =serverNamevalue =someserver/>
< property name =databaseNamevalue =someDBName/>
< property name =portNumbervalue =somePortNumber/>
< / bean>
< / property>
< / bean>
<! - 这是bean仅用于数据提取模块 - >
< bean id =sessionFactoryclass =org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> org.hibernate.dialect.SQLServerDialect< / prop>
< prop key =hibernate.format_sql> true< / prop>
< prop key =hibernate.show_sql> true< / prop>
< /道具>
< / property>
< / bean>
< bean id =entityManagerFactoryclass =org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBeanlazy-init =true>
< property name =persistenceXmlLocationvalue =classpath:persistence.xml/>
< property name =dataSourceref =dataSource/>
< property name =jpaDialect>
< bean class =org.springframework.orm.jpa.vendor.HibernateJpaDialect/>
< / property>
< property name =jpaProperties>
<道具>
< prop key =hibernate.dialect> org.hibernate.dialect.SQLServerDialect< / prop>
< prop key =hibernate.format_sql> false< / prop>
< prop key =hibernate.show_sql> false< / prop>
< prop key =hibernate.cache.use_second_level_cache> true< / prop>
< prop key =hibernate.cache.use_query_cache> true< / prop>
< /道具>
< / property>
< / bean>
< bean id =transactionManagerclass =org.springframework.orm.jpa.JpaTransactionManager>
< property name =entityManagerFactoryref =entityManagerFactory/>
< / bean>
指示Spring自动执行带注释的类的
声明式事务管理。 transaction-manager =transactionManager
- >
< tx:注解驱动的事务管理器=transactionManager/>
< / beans>
然后,当我运行带有insert语句的测试时,它们产生如下错误消息: p>
javax.persistence.TransactionRequiredException:执行更新/删除查询
at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl .java:47)
经过深思熟虑之后,我试过了这个:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {classpath:services.xml})
@Transactional = Propagation.REQUIRED)
@TransactionConfiguration(defaultRollback = true)
@TestExecutionListeners(value = {DependencyInjectionTestExecutionListener.class,TransactionalTestExecutionListener.class})
public class SimpleUnitTest {
@Test
public void simpleTest()抛出异常{
System.out.println(entityManager.getTransaction()。isActive());
assertTrue(entityManager.getTransaction()。isActive());
}
}
失败。 entityManager.getTransaction()。isActive()实际上是false。
为什么交易测试不会开始交易?
@TestExecutionListeners(TransactionalTestExecutionListener。类)
或从
扩展<$ p $以获取事务行为。为了获得事务性行为,可以使用
AbstractTransactionalJUnit4SpringContextTests
(请记住,您的测试类不是一个bean,因此常规的事务配置不适用)
I have following configuration.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.IsolationLevelDataSourceAdapter">
<property name="targetDataSource">
<bean class="com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource">
<property name="user" value="user"/>
<property name="password" value="password"/>
<property name="serverName" value="someserver"/>
<property name="databaseName" value="someDBName"/>
<property name="portNumber" value="somePortNumber"/>
</bean>
</property>
</bean>
<!-- this is bean is only used for data extraction module only -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true">
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--
Instruct Spring to perform declarative transaction management automatically
on annotated classes. transaction-manager="transactionManager"
-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
Then, when I ran tests that had an insert statement, they produced error messages as such:
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:47)
After much deliberation, I tried this:
@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());
}
}
And it failed. entityManager.getTransaction().isActive() was in fact false.
Why wouldn't Transactional test does not begin a transaction?
解决方案
You need to either add
@TestExecutionListeners(TransactionalTestExecutionListener.class)
or extend from
AbstractTransactionalJUnit4SpringContextTests
to get transactional behavior. (remember, your test class is not a bean, so regular transaction configuration does not apply)
这篇关于在使用JUnit4进行测试时,Spring @transactional不启动事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!