Spring integration test not rollback

I am using Spring + Hibernate + H2. I perform database operations in my integration tests (by calling a service class). I want Spring to roll back the changes after each testing method, but I cannot get it to work. At first I used MySQL (with MyISAM, which does not support the transaction), but after changing to H2 the problem remains. I tried several DataSource definitions (after reading that this should be XA-aware) but nothing helps.

I use http://code.google.com/p/generic-dao/ for my DAO classes and @ Transactional annotations at my service level (if I delete them, I get the following error: javax.persistence.TransactionRequiredException: transaction not executed).

My test classes are as follows:

@ContextConfiguration("classpath:...spring.xml") @Transactional @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true) public class DemoServiceTest extends AbstractTestNGSpringContextTests{ @Autowired private DemoService demoService; @Test public void addTest() { int size = demoService.findAll().size(); Test coach = new Test(); test.setName("Test"); testService.save(test); Assert.assertEquals(size+1,testService.findAll().size()); } } 

Here is my spring configuration:

 <!-- <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"> --> <!-- <property name="driverClassName" value="org.h2.Driver" /> --> <!-- <property name="url" value="jdbc:h2:~/test" /> --> <!-- <property name="username" value="sa" /> --> <!-- <property name="password" value="" /> --> <!-- </bean> --> <!-- <bean id="myDataSource" class=" com.mchange.v2.c3p0.ComboPooledDataSource"> --> <!-- <property name="driverClass" value="org.h2.Driver" /> --> <!-- <property name="jdbcUrl" value="jdbc:h2:~/test" /> --> <!-- <property name="user" value="sa" /> --> <!-- <property name="password" value="" /> --> <!-- </bean> --> <bean id="myDataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean"> <property name="uniqueResourceName" value="test" /> <property name="driverClassName" value="org.h2.Driver" /> <property name="url" value="jdbc:h2:~/test" /> <property name="user" value="sa" /> <property name="password" value="" /> <property name="maxPoolSize" value="20" /> <property name="reapTimeout" value="300" /> </bean> <bean id="demoDAO" class="...DemoDAOImpl" /> <bean id="demoService" class="...DemoServiceImpl" /> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="test" /> <property name="persistenceXmlLocation" value="classpath:persistence.xml" /> <property name="dataSource" ref="myDataSource" /> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> </property> <property name="jpaVendorAdapter" ref="vendorAdapter" /> </bean> <bean id="vendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="H2" /> <property name="showSql" value="true" /> <property name="generateDdl" value="true" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="searchProcessor" class="com.googlecode.genericdao.search.jpa.JPASearchProcessor"> <constructor-arg ref="metadataUtil" /> </bean> <bean id="metadataUtil" class="com.googlecode.genericdao.search.jpa.hibernate.HibernateMetadataUtil" factory-method="getInstanceForEntityManagerFactory"> <constructor-arg ref="entityManagerFactory" /> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> <tx:annotation-driven /> 

And what is my service implementation:

 @Transactional public class TestServiceImpl implements TestService { private TestDAO<Test,Long> dao; @Autowired public void setDao(TestDAO<Test,Long> dao) { this.dao = dao; } public void save(Test test) { dao.persist(test); dao.flush(); } public List<Test> findAll() { return dao.findAll(); } public Test findByName(String name) { if (name == null) return null; return dao.searchUnique(new Search().addFilterEqual("name", name)); } } 

EDIT: The dao.persist () method basically encapsulates a call to the following method from genericdao (em returns the current EntityManager):

 /** * <p> * Make a transient instance persistent and add it to the datastore. This * operation cascades to associated instances if the association is mapped * with cascade="persist". Throws an error if the entity already exists. * * <p> * Does not guarantee that the object will be assigned an identifier * immediately. With <code>persist</code> a datastore-generated id may not * be pulled until flush time. */ protected void _persist(Object... entities) { for (Object entity : entities) { if (entity != null) em().persist(entity); } } 

Everything works fine, but the changes remain in the database. Any ideas?

+6
source share
1 answer

I think you need to go from AbstractTransactionalTestNGSpringContextTests instead of AbstractTestNGSpringContextTests.

+7
source

Source: https://habr.com/ru/post/898430/


All Articles