Transaction rollback on Spring JDBC tests

Synesso picture Synesso · Oct 29, 2010 · Viewed 27.1k times · Source

I'm trying to get JDBC transaction rollback when using Spring-test without success. When I run the following the SQL update is always committed.

package my.dao.impl;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionConfiguration;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@ContextConfiguration(locations={"classpath:ApplicationContext-test-DAOs.xml"})
@TransactionConfiguration(defaultRollback = true)
public class ConfirmationMatchingDAOImplTest {

    @Autowired
    private DataSource dataSource;

    @Test
    public void shouldInsertSomething() throws Exception {
        final Connection connection = dataSource.getConnection();
        final Statement statement = connection.createStatement();
        statement.executeUpdate("insert into TEST_INSERT values (1, 'hello')");
        statement.close();
        connection.close();
    }
}

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
    <property name="url" value="jdbc:sqlserver://makeitfunky:1490;databaseName=fonzie"/>
    <property name="username" value="ralph"/>
    <property name="password" value="p0n1es_R_kew1"/>
</bean>

What am I doing wrong?

Additionally, am I using too many annotations? Can I make it a bit cleaner?

Answer

Chin Huang picture Chin Huang · Oct 29, 2010

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.