Question

Writting some integration tests in Spring (Like in this question) I will like to avoid the work of a big script to create all tables in HSQL:

<jdbc:script location="classpath:createSchema.sql" />

As Spring is creating and updating my development tables from the model automagically. How could I tell Spring to do the same things for my integration tests?

My datasource file is

<?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:context=  "http://www.springframework.org/schema/context" 
    xmlns:jee=      "http://www.springframework.org/schema/jee" 
    xmlns:p=        "http://www.springframework.org/schema/p"
    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/context               http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee                   http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/jdbc                  http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">        

    <!-- Usamos HSQLDB para hacer las pruebas con in-memory db -->
    <jdbc:embedded-database id="dataSource" type="HSQL">
        <jdbc:script location="classpath:create_schema.sql"/>
        <jdbc:script location="classpath:import.sql"/>           
    </jdbc:embedded-database> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.myProject.model" />
        <property name="hibernateProperties">
        <props>
            <prop key="hibernate.default_schema">TESTING</prop>             
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">create-drop</prop>               
            <prop key="hibernate.show_sql">true</prop> 
        </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

Update: After NimChimpsky answer I had included the schema name in hibernate properties and created a script with just:

CREATE SCHEMA TESTING  

After trying the first insert int the import.sql script I see: org.hsqldb.hsqlexception user lacks privilege or object not found [MyTable]

Was it helpful?

Solution 2

I solved the issue with the help of geoand comment. (Thanks, you should have posted it as an answer). But let me share more information to make future reader's life easier.

First. It seems that telling that you have an script to initializa database makes hibernate to avoid the creation proccess. I changed the code embedded elemento to:

<jdbc:embedded-database id="dataSource" type="HSQL"/>

Hibernate will automatically execute import.sql from the classpath (at least in Create or Create-Drop mode) so there was no need to indicate further scripts. As Spring test framework does rollback the transaction you do no need to restore the database after each test.

Second, I had some problems with my context configuration that needed to be solved if I wanted Spring to create my schema. The best way to do it was to set the ignore failures attribute to "ALL" and look and the logs.

Third. Using HSQL for a few things MySQL for others has its own issues. Syntax is sometimes different and I had to fix my import.sql to become compatible with both databases.

Appart from that, it works:

@ContextConfiguration(locations={"file:src/test/resources/beans-datasource.xml",
                     "file:src/main/webapp/WEB-INF/applicationContext.xml",                                                
                                 "file:src/main/webapp/WEB-INF/my-servlet.xml"})
        @Configuration
        @RunWith(SpringJUnit4ClassRunner.class)
        public static class fooTest{

            @Inject BeanInterface myBean;

            @Test
            @Transactional
            public void fooGetListTest(){

                assertTrue("Expected a non-empty list", myBean.getList().size() > 0 );
            }           
        }
    }

OTHER TIPS

You still need to create schema manually - but literally only the create schema my-schema-name statement, let hibernate create the tables

<jdbc:embedded-database id="dataSource" type="HSQL">
  <jdbc:script location="classpath:create_schema.sql"/>
</jdbc:embedded-database>

If populating the database with values is a problem, yeah it is. No shortcuts really.

And the import script will have to run after the tables are created, in a postconstruct method probably.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top