Unit testing with JUnit for Hibernate using HSQLDB (In-Memory)

Performing JUnit/unit test on hibernate code base can be accomplished using HSQLDB database. HSQLDB provides two ways of implementing this.

    Using file system as database
  • Using HSQLDB in-memory database.

Using in-memory database needs no change to your code other than changes in the hibernate.cfg.xml ( hibernate configuration file). The configuration below uses the hsqldb in-memory database to test an Employee entity.

hibernate.cfg.xml –


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory name="">
  <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
  <property name="hibernate.connection.url">jdbc:hsqldb:mem:testdb;shutdown=false</property>
  <property name="hibernate.connection.username">sa</property><!-- default username -->
  <property name="hibernate.connection.password"/><!-- default password -->
  <property name="hibernate.connection.pool_size">10</property>
  <property name="hibernate.connection.autocommit">true</property>
  <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
  <property name="hibernate.hbm2ddl.auto">create-drop</property><!-- creates the tables from the entites automatically -->
  <property name="show_sql">true</property>
  <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
  <mapping class="blog.hibernate.employee.Employee"/>
 </session-factory>
</hibernate-configuration>


package blog.hibernate.employeeTest;


import static org.junit.Assert.*;

import java.io.File;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.junit.BeforeClass;
import org.junit.Test;

import blog.hibernate.employee.Employee;
import blog.hibernate.employee.EmployeeManager;

public class EmployeeTest {
	
	private static Configuration config;
    	private static SessionFactory factory;
	private static Session hibernateSession;
	
	
	@BeforeClass
	public void init() {
		config = new AnnotationConfiguration();
		config.configure(new File("hibernate.cfg.xml"));
        	factory = config.buildSessionFactory();
        	hibernateSession = factory.openSession();
    	}
	
	@Test
	public void insertEmployee(){
		String empName = "Employee1";
		String empLocation = "India";
		//Add new employee using the session created by HSQLDB configuration
		EmployeeManager.addEmployee(new Employee(empName,empLocation),hibernateSession);
		Employee emp = EmployeeManager.getEmployeeByName(empName,hibernateSession);
		assertEquals("India", emp.getLocation());
	}
}


The hibernate.hbm2ddl.auto option makes sure that there is no need to explicitly create the schema for the entities, but is not true in case of any depending tables that are not a part of the hibernate entities. In such a case, the schema needs to be created explicitly.

It is important to note that the in-memory schema is persisted only for that particular session. Once the session is closed, the schema is lost. If there is a need for persistence across tests ( for different sessions), then the file system DB can be used as an option.

5 thoughts on “Unit testing with JUnit for Hibernate using HSQLDB (In-Memory)

  1. I’m glad to stumble across this blog; an interesting read. I’d assume this method of unit testing, using HSQLDB would apply to legacy code; if you’re writing code from scratch, it should be designed to be unit tested without any DB whatsoever. Of course the queries etc will not be exercised but then you aren’t testing the DB now are you? 🙂
    Add a layer of indirection between your application code and the DB. All your DB specific activities are relegated to this layer and your application should consist of your logic only.
    Mock this indirection layer to run your tests.
    Balu

  2. I don’t agree with you Balu. Sometimes it is necessary to test the queries, not to verify that the DB is executing them correctly, but to verify that you’ve written the write SQL, or HQSQL, or JPAQL. It is very useful to be able to use something like this to perform those type of unit tests.

  3. Hi… Thanks lot for this post…I was struggling how to handle test cases….this solved it.
    Really many thanks….

Leave a comment