Transaction rollback on Spring JDBC tests
If you do not explicitly configure test execution listeners using the @TestExecutionListeners
annotation, Spring configures by default DependencyInjectionTestExecutionListener
, DirtiesContextTestExecutionListener
, and TransactionalTestExecutionListener
. TransactionalTestExecutionListener
provides transactional test execution with default rollback semantics. By explicitly declaring @TestExecutionListeners
on your test class and omitting TransactionalTestExecutionListener
from the listeners list, you are disabling transactional support.
You must also add the @Transactional
annotation at the class or method level.
You must also use DataSourceUtils to get a transactional Connection managed by DataSourceTransactionManager.
If you are using the non-xml method this works nicely since about version 3.1
@Transactional@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {TestDbConfig.class, SomeService.class})public class SomeTest {@Injectprivate SomeService someService;@PersistenceContextprivate EntityManager em;@Testpublic void someTest() {}
The test config then takes this form. Notice @EnableTransactionManagement and the fact you can declare a global test defaultRollback. This becomes particularly useful on a large projects.
@Configuration@PropertySource(value = "classpath:app.properties")@EnableTransactionManagement@TransactionConfiguration(defaultRollback = true)public class TestDbConfig {//read the parameters from properties@Value("${hibernate.dialect:unset}")private String hibernateDialect;@Beanpublic static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer();}@Beanpublic PlatformTransactionManager transactionManager() { //for example JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject()); return transactionManager;}@BeanLocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { //set the datasource //set the JpaVendorAdapter //set the packagesToScan return some sort of LocalContainerEntityManagerFactoryBean;}@BeanDataSource dataSource() { return dataSource from jndi or a DriverManagerDataSource();}
}
add this annotation, and no roll back will be in test cases:
@TransactionConfiguration(defaultRollback=false)
My annotation looks like this:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "/../applicationContext.xml" })@TransactionConfiguration(defaultRollback=true)public class DBCreatorTest {