I use H2 database with Spring, Hibernate and DBUnit for testing. I also use c3p0 connection pool. One of my tests, however strangely fails immediately after it is passes successfully, some exception occurs after the test execution on rollback. My connection URL is jdbc:h2:file:h2/db;MODE=MySQL;LOCK_MODE=0
The following is the test itself.
@Test
public testFindLatestNotSynced() {
BuyWine buyWine = buyWineDao.findLatestNotSynced(1).get(0);
assertNotNull(buyWine);
assertEquals("3", buyWine.getId());
buyWine.setSyncDate(new Date());
buyWine = buyWineDao.findLatestNotSynced(1).get(0);
assertNotNull(buyWine);
assertEquals("1", buyWine.getId());
buyWine.setSyncDate(new Date());
/* Checking empty. */
List<BuyWine> wines = buyWineDao.findLatestNotSynced(1);
assertEquals(0, wines.size());
}
The setup()
and teardown methods are.
@Autowired
private IDatabaseConnection dbUnitConnection;
@Autowired
private FlatXmlDataSetBuilder datasetBuilder;
private ReplacementDataSet dataSet;
...
@Before
public void setUp() throws Exception {
if (initialDatasetName != null) {
/* Using replacement data set, so we can use null values in the first row. */
dataSet = new ReplacementDataSet(
datasetBuilder.build(getClass().getResourceAsStream(initialDatasetName)));
dataSet.addReplacementObject("[NULL]", null);
dataSet.setStrictReplacement(true);
DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, dataSet);
}
}
@After
public void tearDown() throws Exception {
if (dataSet != null) {
DatabaseOperation.DELETE_ALL.execute(dbUnitConnection, dataSet);
}
dbUnitConnection.close();
DataSourceUtils.releaseConnection(connection, dataSource);
}
It looks very much like a bug in H2, but I want to figure out some workaround for that.
The stack trace of the exception is:
org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: rollback failed
at org.springframework.orm.hibernate4.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:577)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:846)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:823)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:588)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:297)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:192)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:395)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:91)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.hibernate.TransactionException: rollback failed
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:215)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:574)
... 28 more
Caused by: org.hibernate.TransactionException: unable to rollback against JDBC connection
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:167)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:209)
... 29 more
Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.ArrayIndexOutOfBoundsException: 0"; SQL statement:
ROLLBACK [50000-174]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
at org.h2.message.DbException.get(DbException.java:161)
at org.h2.message.DbException.convert(DbException.java:284)
at org.h2.table.RegularTable.removeRow(RegularTable.java:394)
at org.h2.engine.UndoLogRecord.undo(UndoLogRecord.java:98)
at org.h2.engine.Session.rollbackTo(Session.java:586)
at org.h2.engine.Session.rollback(Session.java:554)
at org.h2.command.dml.TransactionCommand.update(TransactionCommand.java:50)
at org.h2.command.CommandContainer.update(CommandContainer.java:79)
at org.h2.command.Command.executeUpdate(Command.java:253)
at org.h2.jdbc.JdbcConnection.rollbackInternal(JdbcConnection.java:1445)
at org.h2.jdbc.JdbcConnection.rollback(JdbcConnection.java:470)
at com.mchange.v2.c3p0.impl.NewProxyConnection.rollback(NewProxyConnection.java:860)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:163)
... 30 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at org.h2.index.PageBtree.getRow(PageBtree.java:172)
at org.h2.index.PageBtreeLeaf.remove(PageBtreeLeaf.java:228)
at org.h2.index.PageBtreeIndex.remove(PageBtreeIndex.java:239)
at org.h2.table.RegularTable.removeRow(RegularTable.java:376)
... 40 more