mdarwin
mdarwin

Reputation: 2404

HSQLDB + junit : intermittent "connection exception: closed"

I am seeing a strange problem when using HSQLDB in my unit test.

I have a unit test using in-memory HSQLDB which is failing intermittently with the following:

org.hsqldb.HsqlException: connection exception: closed

along with

org.hsqldb.HsqlException: connection exception: connection does not exist

My suspicion is that the in-memory DB is somehow persisting between the different test runs.

My test looks like this:

private static final String DRIVER = "org.hsqldb.jdbc.JDBCDriver";
private static final String URL = "jdbc:hsqldb:mem:test2";

@BeforeClass
public static void init() throws SQLException, ClassNotFoundException, IOException {
    Class.forName(DRIVER);
    populateDatabase();
}

private static Connection getConnection() throws SQLException {
    return DriverManager.getConnection(URL, user, user);
}

private static void populateDatabase() throws SQLException {
    try (Connection connection = getConnection(); Statement statement = connection
            .createStatement()) {
        statement.execute(
                "CREATE TABLE employee (name VARCHAR(50) NOT NULL, "
                        + " age INT NOT NULL, outputcol FLOAT)");
        connection.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@AfterClass
public static void destroy() throws SQLException, ClassNotFoundException, IOException {
    try (Connection connection = DriverManager
            .getConnection(URL + ";shutdown=true", user, user);
            Statement statement = connection.createStatement()) {
        statement.executeUpdate("DROP TABLE employee");
        connection.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The fact that the error is inconsistent points to something hanging around in memory between test runs, which is bizarre.

I have tried:

Note that the test should create a DB in memory, then pass the credentials to the class under test, which uses those credentials to connect via DriverManager. After the test is over, we drop the tables and basically want to then empty and destroy the DB.

I'm running these tests from the command line with mvn clean install.

Upvotes: 2

Views: 656

Answers (1)

fredt
fredt

Reputation: 24372

The semantics of ;shutdown=true added to a URL is as follows:

  • it is effective on the first connection to the database, not on subsequent connections

  • when the last connection is closed (by calling the close() method), the database is also shutdown

You can execute SHUTDOWN as an SQL statement in your destroy() method, instead of counting on all connections getting closed.

Upvotes: 1

Related Questions