Transaction rollback on Spring JDBC tests

时光毁灭记忆、已成空白 提交于 2019-12-05 01:25:13

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 {

@Inject
private SomeService someService;

@PersistenceContext
private EntityManager em;

@Test
public 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;

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

@Bean
public PlatformTransactionManager transactionManager() {
    //for example
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
    return transactionManager;
}

@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    //set the datasource
    //set the JpaVendorAdapter
    //set the packagesToScan
    return some sort of LocalContainerEntityManagerFactoryBean;
}

@Bean
DataSource 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 {

Could it be because you do not have an @Transactional for the test method?

jkatt

When using the @Transactional annotation in Spring, you must add the following line to your Spring configuration file:

<tx:annotation-driven transaction-manager="transactionManager"/>

The transaction-manager property holds a reference to the transaction manager bean defined in the Spring configuration file. This code tells Spring to use the @Transaction annotation when applying the transaction interceptor. Without it, the @Transactional annotation is ignored, resulting in no transaction being used in your code.

Source on IBM website

additional informations :

for this line

<tx:annotation-driven transaction-manager="transactionManager"/>

The default value of the transaction-manager attribute is "transactionManager". This attribute is required only if the bean id/name of the transactionManager is not 'transactionManager'. So you just have to set :

<tx:annotation-driven />

You need to add @Transactional at class level. Something like this :

@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
@Transactional

Here txManager is an instance or bean id of Transaction manager from application context.

<!-- Transaction Manager -->
    <bean id="txManager"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:annotation-driven transaction-manager="txManager" />

After trying out a lot of the above combinations, the following setup worked for me with full rollback after the test is successful.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:datasource-context-test.xml"})
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class DataAccessTest 
{


    @Test
    public void testSaveRecords()
    { ... }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!