2010-06-27 7 views
4

Mes tests d'intégration DAO échouent car les entités créées pendant les tests sont toujours dans la base de données au début du test suivant. Le même comportement est vu à la fois de MySQL 5 et H2.Le test d'intégration DAO Spring/JTA/JPA ne redémarre pas?

Les classes de test sont annotés avec:

@Transactional 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({ "/testPersist-applicationContext.xml" }) 

La configuration de la fève de transaction dans le cadre de l'application de test est la suivante:

<tx:annotation-driven /> 

<bean id="transactionManager" 
class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManager" ref="atomikosTransactionManager" /> 
    <property name="userTransaction" ref="atomikosUserTransaction" /> 
</bean> 

<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 
init-method="init" destroy-method="close"> 
    <property name="forceShutdown" value="false" /> 
</bean> 

<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> 
    <property name="transactionTimeout" value="300" /> 
</bean> 

Le gestionnaire d'entités est configuré comme suit:

<bean id="myappTestLocalEmf" 
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="myapp" /> 
    <property name="persistenceUnitPostProcessors"> 
     <bean    class="com.myapp.core.persist.util.JtaPersistenceUnitPostProcessor"> 
     <property name="jtaDataSource" ref="myappPersistTestJdbcDataSource" /> 
     </bean> 
    </property> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="showSql" value="false" /> 
      <property name="database" value="$DS{hibernate.database}" /> 
      <property name="databasePlatform" value="$DS{hibernate.dialect}" /> 
     </bean> 
    </property> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup 
      </prop> 
      <prop key="hibernate.format_sql">true"</prop> 
      <prop key="hibernate.use_sql_comments">true</prop> 
      </props> 
    </property> 
</bean> 

<context:annotation-config /> 

Tout dans les fichiers journaux semble être bien ... Je peux voir les messages de Spring à propos de rollback et d'Atomikos à propos de rollback aussi. Mais franchement, les journaux sont si énormes et si complexes, je pourrais facilement manquer quelque chose ...

Pourtant, les données de test insérées restent! Des indices?

Répondre

6

Il est avéré que ma source de données JDBC C3P0 n'a pas été XA au courant et n'a donc pas participé à la transaction. Pourquoi je n'ai pas eu une erreur, ni un avertissement dans le fichier journal, je ne sais pas. Néanmoins, la raison pour laquelle vous ne pouvez pas utiliser une source de données compatible XA est très bien expliquée here. Notez que la source de données n'a pas besoin d'être compatible XA ... juste au courant de XA. Le remplacement de la source de données C3P0 par la suivante a permis de résoudre le problème.

<bean id="myappJTANonXADataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean"> 
     <property name="uniqueResourceName" value="myappDatabase" /> 
     <property name="driverClassName" value="$DS{hibernate.connection.driver_class}" /> 
     <property name="url" value="$DS{hibernate.connection.url}" /> 
     <property name="user" value="$DS{hibernate.connection.username}" /> 
     <property name="password" value="$DS{hibernate.connection.password}" /> 
     <property name="maxPoolSize" value="20" /> 
     <property name="reapTimeout" value="300" /> 
</bean> 
+1

Merci beaucoup, eu un problème similaire (sans le printemps) et ça m'a aidé – Ittai

1

Je pense que vous aurez besoin de parcourir les journaux dans les détails. Il se peut que les annulations que vous voyez fonctionnent, sauf que quelque chose d'autre a d'abord exécuté un commit. Je ne peux pas non plus voir quoi que ce soit dans votre code qui indique une restauration automatique. Et que cela devrait se produire à la fin de chaque test. Si vous dépendez d'une annulation basée sur le délai d'attente, il se peut que le second test soit en cours avant que le délai ne soit dépassé. Par conséquent, il voit les données avant qu'elles ne soient annulées.

De nombreuses options ici il y a :-)

+0

Le coureur de test de ressort fait le rollback. Je peux voir Spring Test et Atomikos créer la transaction et également exécuter la restauration. Cependant, il semble que la connexion de données Hibernate/JDBC ne doit pas être synchronisée correctement. Juste pour m'assurer qu'il ne s'agissait pas d'un problème Spring Test, C3P0, JDBC ou Hibernate, je suis passé à une unité de persistance RESOURCE_LOCAL avec la source de données injectée directement dans mon gestionnaire d'entités et tout a fonctionné comme prévu. Donc, le problème est avec Atomikos et/ou mon post-processeur contourner le manque de JNDI en dehors d'un serveur d'applications. – HDave

Questions connexes