Java Persistence (JPA) with JBoss

A major enhancement in EJB technology is the addition of the new Java Persistence API (JPA), which simplifies the Entity persistence model and adds capabilities that were not in EJB 2.1 technology. The Java Persistence API draws on ideas from leading persistence frameworks and APIs such as Hibernate, Oracle TopLink, and Java Data Objects (JDO), and well as on the earlier EJB container-managed persistence.

 

With Java EE 5, most of the XML configurations have been relegated to annotations.

Like the SLSB, the Entity is going to be a POJO, which will help provide us the most flexibility when creating the domain there. The Entity will look like a regular JavaBean representing a table in the database. Each of the properties will be assumed to be a persistable column on the database. This will then allow us to use EntityManager (which we will discuss in a bit) to perform operations on it that will be translated to our table.

EntityManager can be called from any class, but preferably we would want to call it from a Session Bean implementing the well famous Session Facade pattern.

So take for example the Class Note which contains some information about a trouble ticketing system

package com.sample;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "NOTE")

public class Note implements Serializable {
long noteId;

String text;

String actor;

String attachment;

@Id
@GeneratedValue
public long getNoteId() {
 return noteId;
}

public void setNoteId(long noteId) {
 this.noteId = noteId;
}

public String getActor() {
 return actor;
}

public void setActor(String actor) {
 this.actor = actor;
}

public String getAttachment() {
 return attachment;
}

public void setAttachment(String attachment) {
 this.attachment = attachment;
}

public String getText() {
 return text;
}

public void setText(String text) {
 this.text = text;
}
}

Here you can see a few annotations: at fist the Entity annotation which declares the Bean as Entity Bean. Then we have the Table annotation which is not mandatory but usually useful because naming conventions for DB Tables and Java classes usually don’t collide. Let’s go on: The @Id annotations defines the field as the primary key of the table: s.

What’s the right place for the @Id tag ? You can either add the annotation above the class field or on the getter method of the field. If you place it on the setter method it will be ignored.

Along with the @Id there’s the @GeneratedValue annotation. This is used with the @Id annotation when you have a value that is generated. The following are the types of strategies allowed (the default is AUTO):

AUTO: Indicates that the database should automatically pick the appropriate type
TABLE: Indicates that the database should have an underlying table referencing this unique ID
IDENTITY: Indicates that the database should use this field as an identity column
SEQUENCE: Indicates that the database should use a sequence column to get the column

If you need an example of an Entity structured with a Sequence here’s one short tutorial . Aren’t we forgetting something ? what about column name mappings ? well as default the Container will try to map the EJB field with Database table name if they are the same. However, if you need to have a different name, you can use the @Table annotation.
So if your text field were named TICKETTEXT in your table , your class would look like:

@Column(name="TICKETTEXT")
  public String getText() {
  return text;
}

How do you connect to your DataSource?

Just write a simple file named persistence.xml file which defines the provider for the data source. In this case we suppose we have a Datasource registered with the Jndi Name”ORACLEDS“. Since we are using JBoss as the container, we will be using the Hibernate persistence provider. Then we provide the JNDI name so that the application server can provide a name to the associated data source instance classes. 

<persistence>

 <persistence-unit name="userDatabase">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <jta-data-source>ORACLEDS</jta-data-source>
    <properties>
      <property name="hibernate.dialect" 
       value="org.hibernate.dialect.OracleDialect"/>
    </properties>
 </persistence-unit>
</persistence>

Important Update: When using JBoss AS 5.x – 6.x persistence.xml needs to conform to a stricter syntax, which includes schema location and persistence version. Here’s how you would connect using JPA 2 on JBoss AS 6

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">

 <persistence-unit name="userDatabase">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <jta-data-source>ORACLEDS</jta-data-source>
    <properties>
      <property name="hibernate.dialect" 
       value="org.hibernate.dialect.OracleDialect"/>
    </properties>
 </persistence-unit>
</persistence>

 

 

Writing a Session Bean facade

Now your Entity Bean is ready, we’ll concentrate on the Session Bean which will be our facade for our Entities.

A session bean facade can be used to encapsulate the complexity of interactions between the business objects participating in a workflow. The Session Facade manages the business objects, and provides a uniform coarse-grained service access layer to clients.

 

import java.io.Serializable;

import java.util.List;

import javax.ejb.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.annotation.ejb.Clustered;

@Stateless

public class HelloBean implements 
                          HelloBeanItf, Serializable {


@PersistenceContext(unitName="userDatabase")
private EntityManager em;


 public List<Note> findAll() {
  Query query = em.createQuery("Select h from Note h");
  return (List<Note>) query.getResultList();
 }

}

That’s all, besides the Stateless annotation we meet the EntityManager beast ! what is it ?

The Entity Manager is responsible for the entity objects and handling their persistence. The entity manager itself can handle multiple entity instances, the set of which is referred to as a Persistence context. For each record in the database, there will be only one instance of that entity bean stored inside the persistence context.

EntityManager itself comes from factories defined by the EntityManagerFactory interface.
The factory can then create server persistence units. In fact, different factories can reference the same persistence context. We are able to create an EntityManager from the factory via container-managed injection by @PersistenceContext. The parameter unitName contains the equivalent

<persistence-unit name=”userDatabase”> specified in the persistence.xml  file.

Finally, the last type of manipulation you are going to want to do is to find objects by queries. If you are familiar with the Hibernate way of using Query objects to query the database, this will come fairly easy to you.

public List<Note> findAll() {
  Query query = em.createQuery("Select h from Note h");
  return (List<Note>) query.getResultList();
}

In the previous code, we are finding all objects mapped as Note and returning them in a plain java.util.List collection. The language used to query the object is similar to SQL but it’s not regular SQL, it’s called Java Persistence Query Language. This language gives you a way to specify the semantics of queries in a portable way, independent of the particular database you’re using in an enterprise environment. We suggest you for further reading about the JPQL these tutorials:

http://java.sun.com/mailers/techtips/enterprise/2006/TechTips_Oct06.html

http://java.sun.com/javaee/5/docs/tutorial/doc/bnbpz.html

Packaging the EJB Entity application

Packaging the application simply requires that you “jar” your classes (and the persistence.xml file) and copy the file to the “deploy” folder. Here’s how the Entity bean application looks like:

jboss ejb 3 entity
Picture 1: the Entity Bean application “exploded”

Let’s improve our example: how to insert an object ?

quite simple, create the Object as a POJO and pass it to the Entity Manager which will care about persisting it !

Add this to your SLSB:

public void newNote(Note note) {
try {
  em.persist(note);
}
catch (Exception e) {
  e.printStackTrace();
}
}

Then in your Client:

Note newnote = new Note();
newnote.setActor("berth");
newnote.setAttachment("text attached");
newnote.setText("full text");

ejb.newNote(newnote);

Ok but what about deleting an Object ?

Deleting an Object (and therefore a row) from your SLSB requires finding it first and then calling the remove method on the Entity Manager.

public void deleteNote(long noteId) {
  Note note = em.find(Note.class, noteId);
  em.remove(note);
}

Ok but what about updating an Object ?

If you have understood how the EM works you shouldn’t even ask it! anyway it works the same as for Deleting an Object: find it first and change the property you like.

public void deleteNote(long noteId) {
  Note note = em.find(Note.class, noteId);
  note.setText("update the text please!");
}

Which IDE can I use to develop my Entity Beans ?

Without the burden of configuration files you can use any IDE you like. For example here’s how the project would like in a vanilla Eclipse Java Project. You just need to add the libraries which are necessary for Annotations and data persistence. These libraries can be found in the client directory of JBoss installation. 

jboss ejb 3 entity
Picture 2: Eclipse package explorer with the libraries needed to compile the project

Conclusion
In this article we’ve seen how to create a simple Entity Bean which can be deployed to JBoss Server in a matter of minutes. If you missed the article about Session Bean 3.0 read it in the JBoss application server section. 

{fcomment}