I am having trouble setting up a JUnit test that will rollback. I've read a few of these posts here on SO before deciding to write a question, as none seems to be the answer to my problem.
The second test case is failing because data is inserted and persisted in DB from the first test case.
Here's the JUnit test:
package com.company.group.spring.dao;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;
import com.company.group.spring.model.BusObj;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:NAME_OF_CONFIG_FILE.xml"})
@Transactional
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
@TestExecutionListeners({TransactionalTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
public class PerPartsWCDAOTest {
@Autowired
@Qualifier("myBusObjDAO")
private BusObjDAO busObj_dao;
@Transactional
@Test
public void testInsertRollback() {
try {
BusObj busObj = new BusObj("some data...");
assertNotNull(busObj_dao);
assertNotNull(busObj);
busObj_dao.insert(perPartWC);
}
catch (NullPointerException e) {
e.printStackTrace();
}
}
@Transactional
@Rollback(false)
@Test
public void testInsert() {
BusObj busObj2 = new BusObj("some data...");
busObj_dao.insert(perPartWC2);
}
}
Here's the DAOImpl class (the class I'm trying to test):
package com.company.group.spring.dao;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.company.group.spring.model.BusObj;
@Repository("myBusObjDAO")
public class myBusObjDAOImpl implements myBusObjDAO {
private NamedParameterJdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
@Override
public void insert(BusObj someObj) {
String sql = "insert into TABLE (args...) " +
"VALUES (:named_params....)";
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(someObj);
jdbcTemplate.update(sql, paramSource);
}
}
Part of the relevant config:
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@SERVER:PORT:DB"/>
<property name="username" value="USER"/>
<property name="password" value="XXXXXX"/>
</bean>
Edit: +debug print
2012-12-18 08:50:42,177 [main] DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction()] Creating new transaction with name [com.company.group.spring.service.MyClassService.create]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2012-12-18 08:50:42,342 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction
2012-12-18 08:50:42,344 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
2012-12-18 08:50:42,361 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Exposing Hibernate transaction as JDBC transaction [org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler@128647a[valid=true]]
2012-12-18 08:50:42,390 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate.update()] Executing prepared SQL update
2012-12-18 08:50:42,391 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate.execute()] Executing prepared SQL statement [insert into TABLE (args...) VALUES (?, ?, SYSDATE,?, ?, SYSDATE, ?,?, ?)]
2012-12-18 08:50:42,391 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection()] Fetching JDBC Connection from DataSource
2012-12-18 08:50:42,657 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection()] Registering transaction synchronization for JDBC Connection
2012-12-18 08:50:42,671 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement()] SQL update affected 1 rows
2012-12-18 08:50:42,678 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection()] Returning JDBC Connection to DataSource
2012-12-18 08:50:42,688 [main] DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback()] Initiating transaction rollback
2012-12-18 08:50:42,688 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doRollback()] Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
2012-12-18 08:50:42,693 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doCleanupAfterCompletion()] Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction
Update: I noticed in the log, it is trying to rollback a Hibernate transaction (but this is JDBC). Then noticed the class for "txManager" is currently org.springframework.orm.hibernate4.HibernateTransactionManager, so I experimented with org.springframework.jdbc.datasource.DataSourceTransactionManager and voila, rollback worked. So I think my problem is more specifically how I'm configuring to use Hibernate and JDBC... I still don't know what is wrong.