I am using Spring 3, and Hibernate 3.5, I am not getting my transactions to rollback in the test environment, which has me worried they would not be rolled back in production either.
Test Class:
@ContextConfiguration(loader = MyConfigurationLoader.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class DashTemplateRepositoryTest extends AbstractMulitpleDataSourceSpringContextTests {
@Autowired
DashTemplateRepository dashTemplateRepository;
@Test
public void testSaveCategory() {
int initialCount = getCategoryCount();
Category c = new Category();
c.setName("mynewcategory");
dashTemplateRepository.save(c);
assertEquals(initialCount + 1, getCategoryCount());
}
}
Which extends a custom class :
public abstract class AbstractTransactionalTemplateTests extends AbstractTransactionalJUnit4SpringContextTests {
protected SimpleJdbcTemplate simpleJdbcTemplate;
@Autowired
DashTemplateRepository dashTemplateRepository;
开发者_如何学C
@Resource(name = "dashDataSource")
public void setDataSource(final DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
} ..snip...
UPDATE: I needed to do the simpleJdbcTemplate insertion because I have multiple dataSources, and by default this test class can't handle that, I wasn't able to find a spring supported solution, but on the spring forums a contributor posted this workaround. The rollback problem existed before I extracted this super class. I'm assuming the problem is more basic than that, hibernate doesn't seem to be aware of the transaction manager, is there any way I can prove that?
Datasource Bean:
<bean id="dashDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/dashtemplate"/>
<property name="username" .../>
<property name="password" .../>
</bean>
My Context-text.xml (simplified, left out some of it)
<!-- Hibernate -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dashDataSource" />
<property name="annotatedClasses">
<list>
<value>com.dash.Category</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="dashTemplateRepository" class="com.wdp.DashTemplateRepositoryHibernateTemplateImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
The test runs fine, my object is persisted, but it is never rolled back, there doesn't appear to be any errors either
The problem was that MySQL was using MyISAM instead of InnoDB - rollbacks are not supported by MyISAM
This is what my base test class looks like and works fine for me.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class BaseTest extends AbstractTransactionalJUnit4SpringContextTests {
//....
}
精彩评论