First Look at Java Persistence API (JPA)

The Java Persistence API (JPA) in original description by sun defines it as

The Java Persistence API provides a POJO persistence model for object-relational mapping. The Java Persistence API was developed by the EJB 3.0 software expert group as part of JSR 220, but its use is not limited to EJB software components. It can also be used directly by web applications and application clients, and even outside the Java EE platform, for example, in Java SE applications.

That is interesting! So let's look a bit deeper into the features of new API.

Persistence deals with entities. An Entitiy is a lightweight domain specific object (in java) that sometimes should or may be stored to persistent storage (e.g. Relational Database). In case of relational db an entity is represented by a Database table and each entity instance corresponds to a row in that table.

Simple JPA entity example

In the Java Persistence API,  persistent state of an entity is represented either through persistent fields or persistent properties. These fields use object-relational mapping annotations to map the entities and entity relationships to the relational data in the underlying data store. So Entities are marked with the @Entity (javax.persistence.Entity) annotation and the entity-class should implement java.io.Serializable interface. Further requirements for entitiy classes can be found in the official Sun Java EE 5 Tutorial.

Let's go through an example

package de.holbreich.chopping;  
import java.io.Serializable;  
import javax.persistence.Entity;  
import javax.persistence.Table;  
import javax.persistence.Column;  
import javax.persistence.Id;

@Entity @Table (name="User") public class Userimplements Serializable { 
  @Id @Column(name="id", nullable=false) private String userId;
  @Column(name="Username") private String username;
  @Column(name="Firstname") private String firstname

  public void setUserId(String userId){ this.userId= userId; }
  public String getUserId() { return this.userId; }
  public void setUsername(String username) { this.username=username; }
  public String getUsername() { return this.username; } 
... 
}

If the entity name is the same as that of the table name, @Table is not required. The same with @Column Attribute. Not Persistent Fields or methods should be marked with @Transient. @Id is required and correspond to a primary key in the Database table. The @Column annotation maps fields to column of the table.
So far its quite simple.

JPA Entities with relations

Entities can maintain relations to each other. Java Persistence API knows four types of multiplicities with corresponding annotations:

  • one-to-one
  • one-to-many
  • many-to-one
  • many-to-many

Furthermore relationships can be unidirectional or bidirectional. In a unidirectional relationship, only one entity has a relationship field or property that refers to the other. This looks really interesting to me.

Inheritance

But there is even more great stuff for example JPA introduces support for inheritance and polymorphism. An entity may inherit from another entity class. By default, the queries are polymorphic and are applicable against the entire entity hierarchy. Read more about inheritance posibilities.

Queries and query language

And finely there is a new and better Query language - The Java Persistence query language (JPQL). JPQL is an extension of the EJB QL, but overcomes EJB QL's limitations and provides more features such as:

  • Bulk update and delete operations
  • Join operations
  • Group-by operations
  • Having operations
  • Projection and sub-queries
  • Support for dynamic queries
  • Use of named parameters (named parameters are parameters in a query that are prefixed with a colon (:))

Management of entities

Entities are managed by javax.persistence.EntityManager. Each EntityManager instance is associated with a persistence context. A persistence context is a set of managed entity instances that exist in a particular data store and defines the scope under which particular entity instances are created, persisted, and removed.

As expected the are two kinds of managers an container managed and one application managed.

Container-Managed Entity Managers

With a container-managed entity manager, an EntityManager instance's persistence context is automatically propagated by the container to all application components that use the EntityManager instance within a single Java Transaction Architecture (JTA) transaction.

//Obtainign Entity Manager
@PersistenceContext(unitName="user")
EntityManager em;  

Application-Managed entity managers

With application-managed entity managers, on the other hand, the persistence context is not propagated to application components, and the life-cycle of EntityManagerinstances is managed by the application.

@PersistenceUnit(unitName="user")
EntityManagerFactory emf;  
EntityManager em = emf.createEntityManager();  

Application-managed entity managers don’t automatically propagate the JTA transaction context. Such applications need to manually maintain transactions. The javax.transaction.UserTransaction interface defines methods to begin, commit, and roll back transactions. Inject an instance of UserTransaction by creating an instance variable annotated with @Resource:

@PersistenceContext
EntityManagerFactory emf;  
EntityManager em;  
@Resource
UserTransaction utx;  
...
 em = emf.createEntityManager();
  try {
   utx.begin();
   em.persist(SomeEntity);
   em.merge(AnotherEntity);
   em.remove(ThirdEntity);
   utx.commit();
  } catch (Exception e) {
    utx.rollback();
}

Persistent context is described in persistense.xml file

Conclusion

I thik the Java Persistence API is an real cool standard, hope start use it soon. Here are the key features of it summarized:

  • Standardizes the persistence API for the Java platform
  • Brings simplification through a simple POJO-based persistence model
  • Annotations should makes entity coding and deployment easier
  • And of course features like support for inheritance and polymorphism, simplistic entity relationship declaration bring the whole thing to new level.
  • Advantages of JPQL

Furthermore Java Persistence API can be used for Java SE environments too. This is possible because of the Java Persistence API's support outside the EJB container.