Search code examples
javaspringhibernatehsqldbspring-test-mvc

How can I debug processing of hibernate.hbm2ddl.import_files value combined with hsqldb?


In a Java project I'm working on I've got the following setup for our unit tests:

  • I'm using Spring Test MVC, @RunWith(SpringJUnit4ClassRunner.class) and @WebAppConfiguration to run the unit tests, and I create a MockMvc instance using webAppContextSetup(webApplicationContext) to test the application.
  • I've got a Hibernate config to set up an in-memory HSQLDB, all tables are created based on the @Entity classes.
  • In the Hibernate config, I'm setting the hibernate.hbm2ddl.import_files property to load a file import.sql with SQL statements to populate the (in-memory) database.

Now, I've confirmed all these above work:

  • Tests can successfully insert/retrieve from the in-memory DB.
  • The SQL statements in the import.sql are executed, as various tests confirm.

Now the problem: Errors occurring with statements I add in import.sql don't seem to be reported anywhere, neither is any indication given that an error occurred at all. Instead, subsequent statements are simply not executed. (I've confirmed this through testing.)

Is there any way or place these errors are reported that I'm apparently unaware of? Is there an additional Hibernate property for this?

Excerpt from hibernate test config:

    <bean id="sessionFactory" name="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.archive.autodetection">class,hbm</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</prop>
                <prop key="hibernate.connection.username">sa</prop>
                <prop key="hibernate.connection.password"></prop>
                <prop key="hibernate.connection.url">jdbc:hsqldb:mem:myschema</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.hbm2ddl.import_files">configuration/test/import.sql</prop>
                <prop key="hibernate.hbm2ddl.import_files_sql_extractor">org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor</prop>
                <!-- when using type="yes_no" for booleans, the line below allow booleans in HQL expressions: -->
                <prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop>
            </props>
        </property>
    </bean>

Solution

  • I wasn't able to get exceptions to log, like @Julien Kroneg suggested.

    But I was able to put a breakpoint in the catch block of the method org.hibernate.tool.hbm2ddl.SchemaExport#importScript where trimmedSql represents each SQL statement as it's being applied:

    catch ( Exception e ) {
        if (haltOnError) {
            throw new ImportScriptException( "Error during statement execution (file: '"
                    + namedReader.getName() + "'): " + trimmedSql, e );
        }
        exceptions.add(e);
        LOG.unsuccessful(trimmedSql);
        LOG.error(e.getMessage());
    }
    

    It may be enough, given how init scripts are static and not really business data, once you get them to work, they hopefully keep working.