Thursday, April 1, 2010

JPA with Hibernate on Glassfish 3

This post is simply a summary of a simple proof of concept. It shows how to:
  • create a stateless EJB3 bean
  • persist an entity using JPA with Hibernate as a JPA provider
  • configure JPA to use a datastore defined on Glassfish (uses pre-installed java/__default datastore, which uses pre-installed Derby/JavaDB) 
You can download the source code for this sample from here (

public class Book implements Serializable {
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int id;
 private String title;
 private float price;
 public Book() {
Here, I have annotated the property, rather than the getter (not shown for brevity), since it feels more intuitive to me. I don't know if there is any advantage/difference of one vs the other other than my personal preference. The "@GeneratedValue(...)" annotation for primary key in JPA entity definition is not optional, as I expected. Using just the "@Id" annotation results in the primary key being not set (set to 0).

EJB Bean
The interface:
public interface BookManager {
 public abstract int addBook(Book book);
 public abstract Book find(int bookId);

And the bean implementation:
@Stateless(name="BookManager", mappedName = "ejb/BookManagerJNDI")
public class BookManagerImpl implements BookManager {

 // Dependency injection of Entity Manager for
 // the given persistence unit
 @PersistenceContext(unitName="pu1") EntityManager em;
 public int addBook(Book book) {

  // Transitions new instances to managed. On the
  // next flush or commit, the newly persisted
  // instances will be inserted into the datastore.
  return book.getId();
 public Book find(int bookId) {
  return em.find(Book.class, bookId);

The annotation @Stateless with the mappedName make the bean to get registered with JNDI. The
TransactionAttributeType.REQUIRED tells the container to wrap each method in the class with a transaction.
JPA Setup
The persistence.xml file (put it into META-INF folder under src folder so it will be deployed onto the server)
<persistence xmlns="" version="1.0">
    <persistence-unit name="pu1">
     <!-- Persistence provider -->  

   <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
   <property name="" value="create" />
   <property name="hibernate.show_sql" value="true" />

The "hibernate." prefix in persistence.xml file is not optional when adding properties of the JPA provider (Hibernate in this case). They are ignored without it, without a warning.

Glassfish Setup
Nothing other than installing the Hibernate component using the Glassfish console.

Unit Tests
The unit test:
try {   
   InitialContext ctx = new InitialContext();
   BookManager bean = (BookManager) ctx.lookup("ejb/BookManagerJNDI");
   Book book = new Book("Chocolate Rain", 25.10f);
   int bookId = bean.addBook(book );
   book = null;
   book = bean.find(bookId);
   Assert.assertEquals("Chocolate Rain", book.getTitle());
  } catch (NamingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();"Failed. Exception thrown.");

A Few Notes
  • Can JPA be used to create and index? Yes and no. Not in general. But it provides a limited capability. To create a unique constrain on a table, use @UniqueConstraint(columnNames={"EMP_BDAY", "EMP_NAME"})
    • How to specify the character column type length? Use @Column(length=50).
    • What the client can understand about the remote exception, in case the EJB bean fails? The remote exception is wrapped in a EJBException and returned to the client. For example, if the password for the DB is incorrect, the org.hibernate.exception.GenericJDBCException will be returned with a message "Cannot open connection" (when Hibernate is used as JPA provider).
    A few things to try in the next proof of concept:
    • test the rollback function, if second of two persistence operations failed when both are in the same method of the BookManager class.
    • do a parent/child relationship.

    1 comment:

    Artem said...

    thanks for this good post