Printemps / JTA / JPA test de l'unité : la Restauration ne fonctionne pas
Je suis en train de tester une entité EJB3 avec le Printemps.
L'EJB lui-même n'utilise Printemps et je tiens à garder les duplications de la production JPA configuration minimale (c'est à dire de ne pas dupliquer persistence.xml pour l'exemple).
Mes tests d'unité semble fonctionner mais même si mes tests unitaires doivent être transactionnelles, les données sont conservées entre les différentes méthodes de test ...
Voici mon entité :
package sample;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Ejb3Entity {
public Ejb3Entity(String data) {
super();
this.data = data;
}
private Long id;
private String data;
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
Mon test unitaire :
package sample;
import static org.junit.Assert.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/appContext.xml"})
@Transactional
public class Ejb3EntityTest {
@PersistenceContext
EntityManager em;
@Before
public void setUp() throws Exception {
Ejb3Entity one = new Ejb3Entity("Test data");
em.persist(one);
}
@Test
public void test1() throws Exception {
Long count = (Long) em.createQuery("select count(*) from Ejb3Entity").getSingleResult();
assertEquals(Long.valueOf(1l), count);
}
@Test
public void test2() throws Exception {
Long count = (Long) em.createQuery("select count(*) from Ejb3Entity").getSingleResult();
assertEquals(Long.valueOf(1l), count);
}
}
et mon appContext.xml :
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="jotm" />
<property name="allowCustomIsolationLevels" value="true" />
</bean>
<bean id="dataSource" class="org.enhydra.jdbc.standard.StandardXADataSource">
<property name="driverName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:unittest;DB_CLOSE_DELAY=-1" />
<property name="user" value="" />
<property name="password" value="" />
<property name="transactionManager" ref="jotm" />
</bean>
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitPostProcessors">
<bean class="sample.JtaDataSourcePersistenceUnitPostProcessor">
<property name="jtaDataSource" ref="dataSource" />
</bean>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="true" />
<property name="database" value="H2" />
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JOTMTransactionManagerLookup" />
<entry key="hibernate.transaction.auto_close_session" value="false" />
<entry key="hibernate.current_session_context_class" value="jta" />
</map>
</property>
</bean>
</beans>
Quand je lance mon test, test2 échoue parce qu'il trouve 2 entité où je m'attendais à une seule (parce que le premier doit avoir été rollbacked ...)
J'ai essayé beaucoup de différentes configurations et celui-ci semble être la plus complète, je ... je n'ai pas d'autres idées. Faites-vous ?
Parce que je suis en utilisant le @Transactional annotation qui fait de chaque essai l'utilisation de son propre transaction est automatiquement rollbacked d'ici le Printemps.
OriginalL'auteur Michel | 2009-10-05
Vous devez vous connecter pour publier un commentaire.
Quand j'ai essayé d'intégrer JOTM et mise en veille prolongée, j'ai fini par avoir mon code de mise en œuvre de ConnectionProvider. Voici à quoi il ressemble maintenant: http://pastebin.com/f78c66e9c
Ensuite, vous spécifiez votre mise en œuvre, comme la connexion privider dans hibernate des propriétés et des opérations de magie de commencer à travailler.
Le truc, c'est que la connexion par défaut du fournisseur d'appels getConnection() sur la source de données. Dans votre propre application vous appelez getXAConnection().getConnection(). Ce qui fait la différence
OriginalL'auteur artemb
J'ai réussi à le faire fonctionner à l'aide de Bitronix au lieu de JOTM. Bitronix fournit un LrcXADataSource qui permet à un non XA base de données afin de participer à la transaction JTA.
Je pense que les questions ont été H2 n'est pas XA conforme et le enhydra
StandardXADataSource
ne fait pas de la magie (j'ai aussi fini à l'aide de HSQLDB, mais qui est sans rapport avec la question).Ici, est mon de printemps contexte qui fonctionne :
OriginalL'auteur Michel
Edit: (Désolé, me semble que je n'avait qu'à moitié éveillé quand j'ai écrit ce paragraphe. Bien sûr, vous avez raison, tout devrait être annulée par défaut.)
Vous pouvez vérifier ce que le gestionnaire de transactions est vraiment en train de faire, par exemple en permettant la sortie de débogage.
En supposant que log4j:
La transaction manager vous donne une très belle sortie de journal à propos de créé et a rejoint les transactions, et aussi sur les validations et les restaurations. Qui devrait vous aider à trouver ce qui ne fonctionne pas avec votre configuration.
OriginalL'auteur Henning
Ajouter @Restauration d'annotation (à partir de org.springframework.test.annotation), juste après le @Transactional annotation comme mentionné dans le ressort de la documentation.
OriginalL'auteur Nageswara RaO Maridu