2010-07-28 113 views
10

我有以下配置。Spring @transactional在使用JUnit4进行测试时未启动事务

<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> 

然后,当我跑测试,有一个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()实际上是false。

为什么交易测试不会开始交易?

+0

它看起来像你有一个正确的配置,但缺少一些东西。 DEBUG [AnnotationTransactionAttributeSource]使用属性PROPAGATION_REQUIRED,ISOLATION_DEFAULT;'在上下文加载阶段和以后的版本中添加事务性方法'XXX'DEBUG [HibernateTransactionManager]创建名为[XXX]的新事务:PROPAGATION_REQUIRED,ISOLATION_DEFAULT'当测试运行时。所以我相信,交易就在那里。 – 2010-09-27 17:10:36

+0

您是否设法解决此问题? – ziggy 2012-06-06 22:13:25

+0

您是否尝试过使用TransactionTemplate而不是@Transactional注释? – stringy05 2015-02-25 00:43:04

回答

4

您需要可以添加

@TestExecutionListeners(TransactionalTestExecutionListener.class) 

AbstractTransactionalJUnit4SpringContextTests 

延伸到获得交易行为。 (请记住,您的测试课程不是豆类,因此常规交易配置不适用)

+0

我尝试过使用这两个,但我没有获得太大的成功。我试过@RunWith(SpringJUnit4ClassRunner.class)会让测试类被Spring识别吗?没有? 我应该如何配置测试以使用您建议的那两个? – 2010-08-02 01:01:41

+0

我编辑了我的原始问题,以反映您在提出建议后所尝试的内容。 – 2010-08-02 03:05:18

0

如果您使用SpringJUnit4ClassRunner,则默认启用TransactionalTestExecutionListener

您需要确保您在您的测试方面的配置中,交易管理配置:

@Autowired 
private PlatformTransactionManager transactionManager; 

如果相关:

@ContextConfiguration(locations = { "classpath:services.xml" }) 

所以,你可以通过注入TM豆检查出来没有解决,那么事务配置没有正确定位。

在调试测试过程中,检查堆栈跟踪中的TransactionInterceptor

+0

我有你说的一切,但是,我注意到在日志中没有任何交易开始的痕迹。我曾经在交易开始时看到以下日志: INFO - 开始交易(1):交易管理器 请参阅我的新问题:http://stackoverflow.com/q/28669280/353985 – redochka 2015-02-23 08:08:38

0

因为你有两个与配置有关的答案,我想问题不在于配置,而在于如何检查事务是否处于活动状态,以及如何获取该实例的问题。

可能的问题可能是:使用EntityManagerFactory.createEntityManager()方法代替注入EntityManager

相关问题