Here's my test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:repositoryContextTest.xml" })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class SeasonITest {
@Autowired
private SeasonDao seasonDao;
@Test
public void createSeason() throws Exception {
Season season = new Season();
season.setName("2012");
seasonDao.createSeason(season);
}
and the dataSource in my bean configuration file
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/tournament_system" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="defaultAutoCommit" value="false"/>
<property name="poolPreparedStatements" value="false"/>
<property name="maxOpenPreparedStatements" value="0"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
When I run this test there a new record is created in my database.
How can I rollback this transaction?
This is the log output I see:
2012-06-15 15:00:02,173 [main] INFO - ionalTestExecutionListener -
Rolled back transaction after test execution for test context
[[TestContext@76db09 testClass = SeasonITest,
locations = array<String>['classpath:repositoryContextTest.xml'],
testInstance = org.toursys.repository.dao.SeasonITest@1265109,
testMethod = createSeason@SeasonITest, testException = [null]]]
UPDATE:
all answers below want to change logic or database engine what I dont want. So I am offering reputation point to the right answer:
Why when I have this: @TransactionConfiguration(defaultRollback = true)
in transaction configuration tests are not rolled back and how I can fix it ?
If you are using MySQL with MyISAM engine try switching to InnoDB.
For more complicated test you will probably need a mocking framework or DB recreation.
EDIT1: According to the documentation InnoDB is transactional with full ACID support while MyISAM has support for atomic operations. More reading: Transaction and Atomic Operation Differences
EDIT2: In @TransactionConfiguration the default value for defaultRollback is true, so instead of commenting the line you should add @TransactionConfiguration(defaultRollback=false)
On the surface, your code and configuration looks correct. However, could you please post your SeasonsDAO object. We would first need to verify that the SeasonsDAO is correctly configured for transactions.
SeasonsDAO needs to be participating in the same TransactionContext as your test case and there is no way to verify that with the code you posted.
Did you mark SeasonsDAO as @Transactional ?
If it is not, I am not sure how the TransactionProxyFactoryBean would be able to proxy and declaratively manage the transaction.
At a high level, spring uses the notion of proxying to perform many services such as transaction management.
If you mark something as @Transactional, Spring will dynamically create a proxy that will implement the same interfaces as your target class. Once it is proxied, a transaction interceptor will wrap method calls to your target class and decide whether to rollback or commit based on defaults or rules that you may specify.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With