How can I wipe data from my HSQLDB after every test?

此生再无相见时 提交于 2019-11-28 04:05:50
  1. You can clear the data by dropping the schema. The default schema is called PUBLIC. If you execute the SQL satement below, it will clear all data and drop all tables.

    DROP SCHEMA PUBLIC CASCADE

  2. Alternatively, if you need the table and schema object definitions, you can create a file: database containing the objects but no data, and add the property below to the .properties file. Using this type of database for tests, the changes to data are not persisted

    files_read_only=true

  3. The latest alternative, available in HSQLDB 2.2.6 and later allows you to clear all the data in a schema while keeping the tables. In the example below, the PUBLIC schema is cleared.

    TRUNCATE SCHEMA public AND COMMIT

    This statement has been enhanced in the latest versions of HSQLDB. See http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement under Truncate Statement

user799188

Following fredt's advice, TRUNCATE SCHEMA PUBLIC RESTART IDENTITY AND COMMIT NO CHECK worked for me. Relevant part of code in the JUnit test for the DAO.

@After
public void tearDown() {
    try {
        clearDatabase();
    } catch (Exception e) {
        fail(e.getMessage());
    }
}


public void clearDatabase() throws Exception {
  DataSource ds = (DataSource) SpringApplicationContext.getBean("mydataSource");
  Connection connection = null;
  try {
    connection = ds.getConnection();
    try {
      Statement stmt = connection.createStatement();
      try {
        stmt.execute("TRUNCATE SCHEMA PUBLIC RESTART IDENTITY AND COMMIT NO CHECK");
        connection.commit();
      } finally {
        stmt.close();
      }
    } catch (SQLException e) {
        connection.rollback();
        throw new Exception(e);
    }
    } catch (SQLException e) {
        throw new Exception(e);
    } finally {
        if (connection != null) {
            connection.close();
        }
    }
}

According to documentation at http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement

If RESTART IDENTITY is specified, all table IDENTITY sequences and all SEQUENCE objects in the schema are reset to their start values

What we do in all our tests is that we rollback the transaction at the very end of execution (after all assertions are through). We use Spring and by-default tests don't commit at the very end. This ensures that you always return to the starting state of the database (after initial creation of entity tables and running of import.sql).

Even if you don't use Spring, you can probably roll your own try {} finally {} block to rollback a started transaction for each test.

Another solution is listed in "Clearing the database between tests" http://www.objectpartners.com/2010/11/09/unit-testing-your-persistence-tier-code/

I had a simple SQL script that was run before each test with the following statement at the beginning:

TRUNCATE SCHEMA public AND COMMIT;

but I have run into lock problems between tests and adding this worked for me like a charm:

@After
public void after() throws Exception {
    if (entityManager.getTransaction().isActive()) {
        entityManager.getTransaction().rollback();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!