Search code examples
javahibernatepostgresqlhsqldbdbunit

Using hsqldb with Ibatis to test a configuration that relies on Postgres in production


There is a current migration in the test environment to rely on DBunit + HSQLDB. I am experiencing the Nextval issue. My ibatis configuration file looks like so:

<select id="selectTestKey" resultMap="integerResult">
        select nextval('test_seq') as integer
    </select>

My Spring mapping file looks like so:

<bean id="testDS" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
        <property name="url" value="jdbc:hsqldb:mem:test;sql.syntax_pgs=true" />
        <property name="username" value="SA" />
        <property name="password" value="" />
    </bean>

Relevant Hibernate error:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: Error preparing statement.  Cause: org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: NEXTVAL

This works correctly against an Postgres database, yet fails against HSQLDB. The other answers on this site did not provide a solution for me.

Using the following maven config to get hsqldb:

<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.2.8</version>
</dependency>

Solution

  • NEXTVAL, etc. all work in the Posgres compatibility mode. As you can verify by double clicking the hsqldb.jar and checking in the GUI DatabaseManager with your URL, a CREATE SEQUENCE statement and your NEXTVAL statement.

    It is possible that the version of HSQLDB actually used is older than 2.2.8 and does not support the NEXTVAL feature. You can add a check to the URL, which results in connection failure if the database does not support the given syntax property.

    jdbc:hsqldb:mem:test;sql.syntax_pgs=true;check_props=true
    

    It is also possible that the full URL is not sent to HSQLDB, which would be the case if the above URL connects, but NEXTVAL does not work.