Wednesday, November 3, 2010

Quickest JPA test-setup ever!

Have you ever wanted to test some JPA functionality? Were you discouraged to do so because of the long setup process?
I wanted to test some JPA functionality without the hassle of setting up a DB and configuring XML files, A simple, short piece of code that I was able to run immediately.

This can be done very easily with in-memory HSQLDB and configuration using annotations. You only need Hibernate and HSQLDB on your classpath.
Take a look:

package jpa;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.ejb.Ejb3Configuration;

@Entity
public class SimpleEntityTest
{
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    public SimpleEntityTest()
    {
    }
 
    public Long getId()
    {
        return id;
    }
    
    public void setId( Long id )
    {
        this.id = id;
    }
    
    public String getName()
    {
        return name;
    }
    
    public void setName( String name )
    {
        this.name = name;
    }
    
    @SuppressWarnings("unchecked")
    public static void main( String[] args ) throws Exception
    {
        Ejb3Configuration cfg = new Ejb3Configuration();
        cfg.setProperty( "hibernate.connection.driver_class", "org.hsqldb.jdbcDriver" );
        cfg.setProperty( "hibernate.connection.username", "sa" );
        cfg.setProperty( "hibernate.connection.password", "" );
        cfg.setProperty( "hibernate.connection.url", "jdbc:hsqldb:mem:test" );
        cfg.setProperty( "hibernate.dialect", "org.hibernate.dialect.HSQLDialect" );
        cfg.setProperty("hibernate.hbm2ddl.auto", "create-drop" );
        cfg.addAnnotatedClass( SimpleEntityTest.class );
        EntityManager em = cfg.buildEntityManagerFactory().createEntityManager();
        
        System.out.println( "create the entity" );
        EntityTransaction trx = em.getTransaction();
        trx.begin();
        SimpleEntityTest ent = new SimpleEntityTest();
        ent.setName( "test" );

        em.persist( ent );
        trx.commit();
     
        System.out.println( "change the entity" );
        trx = em.getTransaction();
        trx.begin();
        List entlist = em.createQuery( "from " + SimpleEntityTest.class.getName() ).getResultList();
        for ( Object object : entlist )
        {
            SimpleEntityTest ent1 = (SimpleEntityTest)object;
            ent1.setName( "other" );
        }
        trx.commit();

        // check with a connection that is not managed by Hibernate
        Connection con = DriverManager.getConnection( "jdbc:hsqldb:mem:test", "sa", "" );
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery( "select name from " + SimpleEntityTest.class.getSimpleName() );
        while ( rs.next() )
        {
            System.out.println( "Entity name: " + rs.getString( 1 ) );
        }
        rs.close();
        stmt.close();
        con.close();
   }
}

Even if you don't have anything installed you can be up and running in minutes using Maven (assuming you have Maven installed and working).
Follow 4 simple steps:
  • Create a Maven project: mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=jpa -DartifactId=jpa-test
  • Copy the above class to jpa-test/src/main/java/jpa
  • replace the pom.xml content with
    
     4.0.0
    
     jpa
     jpa-test
     1.0-SNAPSHOT
     jar
    
     jpa-test
     http://maven.apache.org
    
     
      UTF-8
     
    
     
      
       jboss.org
       Jboss Repo ORG
       default
       http://repository.jboss.org/maven2
       
        false
       
       
        true
       
      
     
    
     
      
       junit
       junit
       3.8.1
       test
      
      
       org.hibernate
       hibernate-core
       3.5.1-Final
      
      
       org.hibernate
       hibernate-annotations
       3.5.1-Final
      
      
       org.hibernate
       hibernate-entitymanager
       3.5.1-Final
      
      
       org.slf4j
       slf4j-api
       1.6.1
      
      
         org.slf4j
         slf4j-nop
         1.6.1
      
      
       hsqldb
       hsqldb
       1.8.0.10
      
     
    
     
      
       
        org.apache.maven.plugins
        maven-compiler-plugin
        
         1.6
         1.6
        
       
      
     
    
    
    
  • Build using Maven or your favorite IDE