2010-07-28 44 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

相關問題