Recently I was doing a new project using JPA, Hibernate, Spring and MySQL and building a generic unit test framework for it. The standard way I have been configuring MySQL with Hibernate was by using org.hibernate.dialect.MySQLDialect. But this was giving strange problems when running transactional unit test cases. The @Rollback(true) annotation was not working at all. At the end of the tests case, what ever database changes are made, they were committed to the database, as if the Rollback annotation do not have any effect at all. I was creating the schema, including tables using Hibernate's schema script creation APIs.
After searching for a solution, finally I found that in the later versions of Hibernate, there are additional dialects for MySQL. There are two more dialects added, MySQLInnoDBDialect and MySQL5InnoDBDialect. So the old usage with org.hibernate.dialect.MySQLDialect will create ISAM tables, which are not transactional. When the dialect was switched to one of InnoDB dialects, the
CREATE TABLE
scripts emit additional ENGINE=InnoDB clause to the DDLs. And the transactions were rolled back properly at the end of the test case.
Spring Configuration
TestModel ${testdb.hibernate.dialect}
Property File
jdbc.testdb.username = user jdbc.testdb.password = pass jdbc.testdb.url = jdbc:mysql://localhost/testdb jdbc.testdb.driver = com.mysql.jdbc.Driver testdb.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
Test Class
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:test-config.xml"}) @TransactionConfiguration(transactionManager="txManager", defaultRollback=false) public class DaoTest { @Before @BeforeTransaction public void setup() { dbCreator.createSchema(); } @Test @Transactional @Rollback(true) public void testSave() { TestModel model = createNewModel(); dao.save(model); }
0 comments:
Post a Comment