EJB3 persistence with hibernate

Since my trip to java posting I looked into EJB3 persistence (JSR-220) with hibernate as promised. It’s shocking how much the EJB3 specification resembles hibernate – Gavin King apparently got most if his hibernate semantics in there. I believe it’s a good thing though. Former hibernate developers can adapt the new sepecification with little effort and on the other hand the definition of persitience classes has been cleaned up nicely with properly defined annotations.
So far I’ve been able to create a simple example application with the hibernate entitymanager/annotations engine. It simply creates two objects, stores them in the database an reads them again with a query. The rest of this post shows how this example app is set up.

Configuration

First of all a configuration file for the database and the persistent classes is needed. The xml file META-INF/persitence.xml is used for that purpose. In my example application I used a local hsqldb database. In addition to the database each persistent class has to be specified in a class-element, in this case example.pojo.Cat.


transaction-type="RESOURCE_LOCAL">
example.pojo.Cat

value="org.hibernate.dialect.HSQLDialect"/> value="org.hsqldb.jdbcDriver"/> value="jdbc:hsqldb:file:database/ejb3test"/> true

Data classes with annotations

As seen above only one persistent class is used in this application. It defines a cat, which has an id, a name and a birth date. In addition to that it also has a parent child relationship as a self reference (attributes mother and kittens). You can also see the annotations which define how all these attributes are persisted. This is the bare minimum of annotations that is required for EJB3 persistence to work. In a more complex application where you want a detailed control over relations, database tables, datatypes and query characteristics the annotations will also look a lot more complex.

package example.pojo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

@Entity
public class Cat {

private String name;
private Date birthDate;
private int id;
private Cat mother;
private List kittens;

public Cat() {
super();
setKittens(new ArrayList());
}

public void addKitten(Cat kitten) {
this.getKittens().add(kitten);
kitten.setMother(this);
}

// -- GETTERs and SETTERs --

@OneToMany(cascade = CascadeType.ALL, mappedBy="mother")
public List getKittens() {
return kittens;
}
public void setKittens(List kittens) {
this.kittens = kittens;
}

@ManyToOne(optional=true)
public Cat getMother() {
return mother;
}
public void setMother(Cat parent) {
this.mother = parent;
}

@Id @GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}

The entity manager

The EJB3 entity manager is what used to the session in hibernate. It provides all functionality to store, update and query objects from the database. In the example code below it is created from a EntityManagerFactory which makes use of the persistence.xml configuration file – you can see the reference to the persistence-unit manager1 here.
Using the entity manager a transaction is started, 2 cats are created, linked as mother and kitten and finally persited with a call to persist() of the entity manager. This step is as simple as with a good old hibernate. Same is true for the query part which follows after that – a parameterized query returns all cats that where born before 1.1.2003.

package example;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import example.pojo.Cat;

public class Test {

public static void main(String[] args) throws ParseException {

// Read configuration from META-INF/persistence.xml
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");

EntityManager em = emf.createEntityManager();

// --------- CREATE CATS -----------

EntityTransaction t = em.getTransaction();
t.begin();

// Create two cats
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Cat mimi = new Cat();
mimi.setName("Mimi");
mimi.setBirthDate(df.parse("2001-03-01"));
em.persist(mimi);

Cat max = new Cat();
max.setName("Max");
max.setBirthDate(df.parse("2003-05-18"));
em.persist(max);

// Mimi is the mother of max
mimi.addKitten(max);

// Commit transaction to store the cats in the database
t.commit();

// --------- QUERY CATS -----------

// Get all cats that where born before 1.1.2003
List catList = em.createQuery(
"select cat from Cat as cat where cat.birthDate < ?1")
.setParameter(1, df.parse("2003-01-01"))
.getResultList();

// Print the list of cats with the number of their children
Iterator catIterator = catList.iterator();
while (catIterator.hasNext()) {
Cat mycat = (Cat) catIterator.next();

System.out.println(mycat.getName() + " children:"+
mycat.getKittens().size());
}

// Close the Entity Manager
em.close();
emf.close();
}

}

Preliminary conclusion

  1. I realize, this simple example doesn't say much about the feature set of EJB3 compared to the hibernate features (caches, optimized queries, relations, etc..). It is a good starting point for further experiments though which is why I provide the example eclipse project as a download including all required libraries. This means this should run in any 3.1 eclipse out of the box.
  2. Did you notice that none of the import statements reference a hibernate specific package? The application only uses the javax.persistence interface so theoretically you should be able to switch from hibernate to any other ejb3 persistence solution without changing a single line of code.
  3. Getting rid of the hibernate mapping files which had to be edited separately from the code or be generated with xdoclet is a big plus in my opinion. I would move my last project from xdoclet tags to annotations in an instant if there wasn't the requirement to use java 1.4.

Download the example

If you like to experiment yourself, download the Ejb3PersistenceTest.zip (5MB) eclipse project. It contains all hibernate libraries (core, entity manager, annotations) to get you started.

2 thoughts on “EJB3 persistence with hibernate

  1. Hello blogger, i must say you have very interesting content here.
    Your website should go viral. You need initial traffic boost only.
    How to get it? Search for; Mertiso’s tips go viral

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>