views:

31

answers:

1

Hi all,

I have 2 test classes, both annotated with the unitils annotation

@DataSet("/dbunit-dataset.xml")

The target database is an HSQLDB, which is initiated in an abstract superclass method annotated with the testng annotation:

@BeforeClass

When the testrunner (Maven Surefire) arrives at the 2nd test, the database is correctly instantiated (I can see that in the logs), but unitils, or actually dbunit, fails to load the dataset.

Caused by: org.unitils.core.UnitilsException: Error while executing DataSetLoadStrategy
        at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:48)
        at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:230)
        at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:153)
        ... 34 more
Caused by: java.sql.SQLException: Access is denied: Session is closed
        at org.hsqldb.jdbc.Util.throwError(Unknown Source)
        at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
        at org.dbunit.database.statement.BatchStatement.executeBatch(BatchStatement.java:59)
        at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:126)
        at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
        at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45)
        at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44)
        ... 36 more

I'm puzzled why dbunit manages to connect to HSQLDB in the first test class, but not in the second one.

Does enybody have a clue?

Thank you! J.

A: 

The following clarifies/answers the problem:

In the @BeforeClass setup method, the HSQLDB instance was recreated for each class, by opening a connection to it:

Class.forName("org.hsqldb.jdbcDriver");
connection = DriverManager.getConnection("jdbc:hsqldb:mem:unit-testing-jpa", "sa","");

And, in the @AfterClass teardown method, the db was removed explicitly:

connection.createStatement().execute("SHUTDOWN");

Recreating the database is not a big issue, unless... DBUnit holds a reference to the database connection and expects to continue working on the same database in every testcase.

The shutdown=true connection modifier helped a lot...

=> Fix:

(1) Remove the @AfterClass logic: don't shut down the database explictly

(2) Tear down the database declaratively by adding shutdown=true to the initial connection

Class.forName("org.hsqldb.jdbcDriver");
connection = DriverManager.getConnection("jdbc:hsqldb:mem:unit-testing-jpa;shutdown=true", "sa","");

This will make HSQLDB close itself when the last connection is closed.
(See also: http://hsqldb.org/doc/guide/ch04.html)

Jan