2010-07-28 12 views
10

Ich habe folgende Konfiguration.Spring @transactional startet keine Transaktion beim Testen mit 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> 

Dann, wenn ich Tests lief die eine Insert-Anweisung hatte, produzierten sie Fehlermeldungen als solche:

javax.persistence.TransactionRequiredException: Executing an update/delete query 
    at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:47) 

Nach reiflicher Überlegung habe ich versucht, dieses:

@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()); 
    } 
} 

Und es gescheitert. entityManager.getTransaction(). isActive() war tatsächlich falsch.

Warum würde Transaktionstest nicht eine Transaktion beginnen?

+0

Es scheint, als ob Sie eine korrekte Konfiguration haben, aber etwas fehlt. Logs aktivieren, in meinem sehe ich 'DEBUG [AnnotationTransactionAttributeSource] Hinzufügen der Transaktions Methode 'XXX' mit dem Attribut: PROPAGATION_REQUIRED, ISOLATION_DEFAULT;' beim Laden des Contexts und später 'DEBUG [HibernateTransactionManager] Erstellen einer neuen Transaktion mit dem Namen [XXX]: PROPAGATION_REQUIRED, ISOLATION_DEFAULT' wenn der Test ausgeführt wird. Ich bin mir sicher, die Transaktion ist da. –

+0

Haben Sie das Problem gelöst? – ziggy

+0

Haben Sie dies mit einem TransactionTemplate anstelle der @Transactional-Annotationen versucht? – stringy05

Antwort

4

Sie müssen entweder

@TestExecutionListeners(TransactionalTestExecutionListener.class) 

hinzufügen oder sich von

AbstractTransactionalJUnit4SpringContextTests 

Transaktionsverhalten zu bekommen. (Denken Sie daran, dass Ihre Testklasse keine Bean ist, daher gilt die normale Transaktionskonfiguration nicht)

+0

Ich habe versucht, diese beiden zu verwenden, aber ich bekomme nicht viel Erfolg. I Thought @RunWith (SpringJUnit4ClassRunner.class) würde die Testklasse von Frühling überhaupt erkannt werden? Nein? Wie sollte ich den Test konfigurieren, um die beiden vorgeschlagenen zu verwenden? –

+0

Ich habe meine ursprüngliche Frage bearbeitet, um zu reflektieren, was ich nach Ihrem Vorschlag versucht habe. –

0

Die TransactionalTestExecutionListener ist standardmäßig aktiviert, wenn Sie SpringJUnit4ClassRunner verwenden.

Sie müssen sicherstellen, dass Sie die Transaktions-Management-Konfiguration in Ihrem Test-Kontext Config sind:

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

So können Sie es durch Injektion des TM-Bean check out:

@Autowired 
private PlatformTransactionManager transactionManager; 

Wenn die Abhängigkeit wird nicht aufgelöst, dann ist die Transaktionskonfiguration nicht richtig lokalisiert.

Überprüfen Sie während des Debuggens Ihres Tests die TransactionInterceptor in Ihrem Stacktrace.

+0

Ich habe alles, was Sie gesagt haben, jedoch habe ich festgestellt, in dem Protokoll gibt es keine Spur von Transaktionsstart. Ich sah das folgende Protokoll, wenn eine Transaktion gestartet wurde: INFO - Beginne Transaktion (1): Transaktionsmanager Siehe meine neue Frage unter: http://StackOverflow.com/q/28669280/353985 – redochka

0

Da Sie zwei Antworten im Zusammenhang mit der Konfiguration erhalten, nehme ich an, das Problem ist nicht die Konfiguration, sondern das Problem, wie Sie überprüfen, ob die Transaktion aktiv ist, und wie Sie diese EntityManager Instanz erhalten.

Ein mögliches Problem könnte sein: EntityManagerFactory.createEntityManager() Methode wird anstelle einer injizierten EntityManager verwendet.

Verwandte Themen