Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 808
Ricardo van den Broek Avatar asked Apr 20 '15 20:04

Ricardo van den Broek


2 Answers

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.

like image 79
DailyFrankPeter Avatar answered Oct 20 '22 01:10

DailyFrankPeter


Not really an answer to your question, but alternative way to handle test DB population.

There is a XML namespace in Spring called jdbc that allows you to prepopulate your database with initial data during Spring context startup. Also it reports errors in your SQLs just fine:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jdbc="http://www.springframework.org/schema/jdbc"
   xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/jdbc
       http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">

    <jdbc:initialize-database data-source="dataSource">
        <jdbc:script location="org/mytestproject/schema-drop-hsqldb.sql" />
        <jdbc:script location="org/mytestproject/schema-hsqldb.sql" />
        <jdbc:script location="org/mytestproject/data-hsqldb.sql" />
    </jdbc:initialize-database>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="validationQuery" value="${jdbc.validationQuery}"/>
    </bean>
</beans>
like image 24
hoaz Avatar answered Oct 20 '22 00:10

hoaz