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

6 comments:

  1. Great article.

    Your pom.xml line 76 is missing closing source tag.

    Also the case of groupid should be groupId and artifactid should be artifactId

    ReplyDelete
  2. pom.xml is not displaying correctly in IE/Firefox

    ReplyDelete
  3. Great stuff for my SCBCD! Thanks!

    ReplyDelete
  4. This is a good example, but I recommend all the code in your main method be moved to a JUnit test class and placed in src/test/java. That way you can have your entity class and a separate test class that can be run as a Maven test of managing the entity using JPA.

    I've set this up in a simple Maven project and can send you the archive if you like.

    ReplyDelete
  5. Regarding the broken XML syntax - it's done by the syntax highlighter. You can view/download the file from http://dl.dropbox.com/u/4926152/pom.xml

    ReplyDelete