Simple Java Persistence API (JPA) Demo Part II

Overview

In this belated installment of the JPA demo series, I will complete what the first installment started. I will look at what happens beyond the basic entities that were defined in the first post. Fill in as much details as possible. Note that this is not meant to be an article gives you all the information that you need to know about JPA. Instead, I will restrict myself to what is relevant in a hands on examination of JPA; there are certainly much more exhaustive information on the subject on the web but we are going to look at appreciating JPA from a hands on perspective. Ok, enough of the reminder.

This installment of the series will dwell on the Entity manager mostly but also touch on any of the parts of JPA that are closely associated with the Entity manager such as Entity Manager Factory and Persistent Context and persistent Units. The post also includes a code sample that shows the creation of an entity manager in action.

The application used to show the concepts behind JPA has a simple structure that also tries to incorporate some aspects of good application design such as separation of concerns which allows the tiers/layers of the application to be as independent from each other as possible.

Entity Manager

Each entity in the domain model goes through a life cycle which typically defines its creation, persistence, retrieval, updates and finally removal. The Entity Manager interface provides methods to enable applications to manage the life cycle of objects in the domain model. You can think of the necessity of the Entity Manager from this perspective: if the Entity class, by its implementation, is not aware of the specifics of the database that will keep its data, then it is a good idea to have another API that will have some understanding of the persistence layer and perhaps even have it as an integral part of the persistence layer. The entity manager players an important role in the architecture of applications that use JPA for persistence.

All entity managers are created from an EntityManagerFactory class; the particular factory class from which an EntityManager is created determines the EntityManager’s configuration. You have the option of application managed (Java SE) EntityManager or Container managed (Java EE) EntityManager. In Java SE there is a bootstrapping class called Persistence that enables you to create an EntityManagerFactory class. However in a Java EE compliant application server you can have the server lookup a Persistent Unit to use in creating the EntityManagerFactory. With the container (Java EE compliant application server for example), you get the option of having the EntityManager injected in your code. The workings of the container managed EntityManager and persistence context is beyond the scope of this series of articles as the objective is to appreciate the JPA with as look support of tools as possible.

In order to get an EntityManagerFactory we need to consider what JPA calls Persistence Context. Though not directly used in JPA applications, the persistence context is closely linked with the EntityManager in a sense that it is the persistence context that defines the entities that are managed by the EntityManager. A persistence context is defined in an XML file which is generally named persistence.xml. In this XML file are persistence units which contains such information as connection parameters (server name, database name, database url, driver, username, password) and any additional properties that can be used by the particular JPA provider. Besides, the connection parameter the persistence unit also specifics the type of transaction that are to be used by EntityManagers so created from the persistence unit.

sample persistence.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<persistence version=”1.0″
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_1_0.xsd”>
  <persistence-unit name=”ContactsService” transaction-type=”RESOURCE_LOCAL”>

<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>model.Client</class>
<class>model.Network</class>
<class>model.AirTimeCard</class>
<class>model.NetworkPrefix</class>
<class>model.Hotel</class>
<class>model.Room</class>
<class>model.Feature</class>
<class>model.FeatureGroup</class>
<properties>

  <property name=”toplink.jdbc.url” value=”jdbc:derby:atbankdb;create=true”/>
  <property name=”toplink.jdbc.driver” value=”org.apache.derby.jdbc.EmbeddedDriver”/>
</properties>

</persistence-unit>

The sample persistence.xml file above defines a persistence unit called “ContactsService” with a transaction type specified as “RESOURCE LOCAL”. This means that we are using entity level transactions which enables us to begin a transaction by calling methods of the EntityManager; specifically em.getTransaction(). We have the option of using JTA (Java Transaction API) which is application for container managed EntityManager. Additional in the persistence unit, we define the provider that we are using. We make use of the toplink Provider. Somewhere in its lifetime, it was owned by Oracle hence the reference to Oracle. TopLink is now an open source project. Other providers that you can use within a persistence unit include Hibernate, OpenJPA and others. The difference is in implementation; for example both Hibernate and OpenJPA are implemented to be as robust as possible with an aim to be relevant to high demand production environments.

As mentioned earlier, the persistence unit defines the entities that are managed within a persistence context which becomes accessible to your code through an EntityManager.

In the Hotel application, since it is a Java SE application, we use the Persistence bootstrap loader to create an EntityManagerFactory.

Code Sample

package controller;

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

/**
* AbstractController class
*
* @author Imma
*/

public abstract class AbstractController
{
    protected EntityManagerFactory emf;

    protected EntityManager getEntityManager(){
        if(emf == null){
            emf = Persistence.createEntityManagerFactory(“ContactsService”);
        }

        return emf.createEntityManager();
    }
}

 

Instead of having to call the bootstrap load in all of our Data Access Layer classes, we can take advantage of inheritance by creating an abstract class with the appropriate method to create an EntityManager. Notice that an EntityManagerFactory is declared as protected, making it accessible to all sub-classes. In addition to that, we have a method that returns an EntityManager for the ContactsService persistence unit (defined in the preceding persistence.xml).

Sample Code

package controller;

import java.util.Collection;
import model.Network;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import model.Hotel;

public class HotelController extends AbstractController
{
    public Collection<Hotel> getHotels(){
        EntityManager em = getEntityManager();

        try{
            Query q = em.createQuery(“SELECT h FROM Hotel AS h ORDER BY h.name”);
            return (Collection<Hotel>) q.getResultList();
        }finally{
            em.close();
        }
    }

    /**
     *
     */
    public Hotel addHotel(Hotel hotel){
        EntityManager em = getEntityManager();
        try{
            em.getTransaction().begin();
            em.persist(hotel);
            em.getTransaction().commit();
            return hotel;
        }finally{
            em.close();
        }
    }

   /**
     * Update Hotel. As you may have already inferred this method is used to update the
     * details of entity (Hotel entity to be exact) that is already stored in the
     * database. We have two options of going about the update.
     * 
     *
     * 1)    We can used the entity manager to locate the entity in the database.
     *       This act of locating the entity gives a managed hotel entity (assuming it
     *       has found in the first place). What this means is that the entity manager
     *       is keep track of any changes made on the attached (managed) entity.
     *

     *       If the retrieval of the entity occurred outside of a transaction, we can
     *       start a transaction; It is within transaction boundaries that the entity’s 
     *       properties are changed and upon committing the transaction, our changes are
     *       then sent to the database.
     *
     * 2)    The second option we have at our disposal is to used the entity manager’s 
     *       merge method. It is not as involving as the method described in one above
     *       which is a good thing if you want to keep your code simple and clean.
     *
     * @return void
     */
    public void update(Hotel hotel){
        EntityManager em = getEntityManager();
        try{
            em.getTransaction().begin();
            em.merge(hotel);
            em.getTransaction().commit();
        }finally{
            em.close();
        }
    }

    public Hotel getHotelById(int hotelId){
        EntityManager em = getEntityManager();
        Hotel hotel = em.find(Hotel.class, hotelId);

        return hotel;
    }

    public Collection<Hotel> getHotelByName(String hotelName){
        EntityManager em = getEntityManager();
        Query query = em.createQuery(“SELECT h FROM Hotel h WHERE h.name LIKE :name“);

  StringBuilder sb = new StringBuilder(“%”);
  sb.append(hotelName);
  sb.append(“%”);

  query.setParameter(“name”, sb.toString());

  return (Collection<Hotel>) query.getResultList();

    }
}

Advertisements
  1. #1 by asif shahzad on October 9, 2008 - 12:43 pm

    Thank you so much for your post.
    I have two questions.
    1. Different terms are used for components that interact with model. you used Controller, other terms are Manager, Service. For example HotelManager, HotelController, HotelService. In your experience, which is more appropriate and why?

    2. I read, we should always close EntityManager after using it. You didnt closed it in getHotelById. Although ’em’ is local to method. Shouldnt we still close it? or it is all right? What is the difference?

    3. When we see queries generated by JPA or Hibernate, it contains a lot of stuff. For example, if i want to modify name of a User. It gets complete object from DB, edit that object, and save it back to DB. Which is very expensive. As system generates extra queries. Which is not the case with pure (or one can say naked) JDBC? then why we used JPA or Hibernate in enterprise applications. Isnt it we are getting flexibility and development-speed at the cost of performance compromise? Or i am missing something.

  2. #2 by asif shahzad on October 9, 2008 - 1:18 pm

    What JPA implementation you personally find the best with respect to performance and why?

    1. Hibernate
    2. Toplink Essentials
    3. CocoBase
    4. OpenJPA

    Thanks

  3. #3 by imma on October 10, 2008 - 7:19 pm

    1. You can name your components in a manner that reflect your design and I believe that will inform you choices of terminologies as well. In this post, I was using a basic MVC design wherein there is a rather strong coupling between the Controller and Model components so the Controller tends to do more. You can have a situation where you have a completely separate business/application layer thus making your controller a series of services that interact with the view/presentation layer. In this regard manager and controller have a close meaning but service components suggest a more elaborate n-tier architecture as opposed to a 3-tier architecture of presentation, web server and database.

    2. Closing the EntityManager will ensure that expensive database connections are not held open but this also depends on the kind of EntityManager you have; container managed EntityManagers may be participating in connection pooling and as such closing the connection outright may negatively affect the performance of your application. In the aforementioned case, it is an application managed EntityManager thus it is a good practice to close the EntityManager thereafter.

    3. When abstracting there is always a price to pay; ORM tools like JPA and/or Hibernate abstract away the details of database query from the developer and the benefit is huge but as you point out, they may not be as efficient as JDBC statements. Having said there are, there are strategies that are used to address the performance penalty that you incur as a result of abstraction. Caching can be used to a great extend to improve performance since the particular implementation of JPA/Hibernate do not need to hit the DB for each and every request.

  4. #4 by imma on October 10, 2008 - 9:09 pm

    I have worked with Hibernate and personally prefer it to other implementation of JPA because it is a lot more mature in comparison; I started using Hibernate way before JPA became a standard so instead of migrating to another implementation all together, I chose to use Hibernate EntityManager and Annotations to take advantage of JPA. It is not an objective reason per se but leveraging existing investments around Hibernate is a main consideration that I take into account.

    Having said that, the other implementation have their place as well based on the task at hand; OpenJPA is certainly powerful and will continue to improve with time. It provides features that are geared towards improving performance and scalability which are key in any non-trivial system.

  1. Software Development In This Day and Age | imma

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: