Showing posts with label jpa. Show all posts
Showing posts with label jpa. Show all posts

Saturday, January 9, 2010

Shopping Cart Web Application - Part 7 - TopLink and EAR

I recently received a response from someone who was stepping through my Shopping Cart Web Application tutorial and who wanted to deploy the application on GlassFish and use TopLink Essentials (EclipseLink) as the reference implementation for JPA as opposed to Hibernate.

Thankfully there wasn't that much change that needed to be made to the existing ShoppingCartHibJpaPart7 application. This application (ShoppingCartTopLinkJpaPart7.zip) is available to download in case anyone would like to take a look. I chose to use EclipseLink which is the successor to TopLink. In order to get it working with GlassFish 2.0 there are a few simple steps to take. The biggest change I needed to make was in the persistence.xml file:

<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_1_0.xsd"
 version="1.0">

 <persistence-unit name="shopping-cart"
  transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <non-jta-data-source>jdbc/__shoppingcart</non-jta-data-source>
  <exclude-unlisted-classes>false</exclude-unlisted-classes>
  <properties>
   <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
   <property name="eclipselink.logging.level" value="FINE" />
  </properties>
 </persistence-unit>
</persistence>
The real difference here is the use of EclipseLink properties as opposed to Hibernate properties. I also had to define the non-jta-data-source attribute. Another one of the requirements was to have GlassFish manage the database connections so my application needed to be configured to lookup the resource via the datasource JNDI name.

Java Transaction API  (JTA) inside a web application
After doing this I was asked if I could change the transaction type from RESOURCE_LOCAL to JTA. In order to do this I made the following changes:

I changed the value of the transaction-type in the persistence.xml file from RESOURCE_LOCAL to JTA and changed the non-jta-data-source attribute to jta-data-source.

Secondly I needed to do a JNDI lookup for the EntityManager managed by the container, one way is to do it by annotation on the Dao class:

@PersistenceContext(name="persistence/ShoppingCart", unitName="shopping-cart")
public class BasketDaoImpl implements BasketDao {

and then the lookup:

Context ctx = new InitialContext();
em =  (EntityManager) ctx.lookup("java:comp/env/persistence/ShoppingCart");

Our application is managing the transaction however in a JTA entity manager entityManager.getTransaction() calls are not permitted so instead I needed to get a UserTransaction by doing a JNDI lookup for the UserTransaction:

Context ctx = new InitialContext();
(UserTransaction)ctx.lookup("java:comp/UserTransaction");

If you are interested in seeing how I implemented this you can download the ShoppingCartJtaTopLinkJpaPart7.zip file and view the DAO classes in the shopping-cart-core-jta-toplink-jpa-part7 project.

BasketDaoImpl.java
@PersistenceContext(name="persistence/ShoppingCart", unitName="shopping-cart")
public class BasketDaoImpl implements BasketDao {

  public Basket updateBasket(Basket basket) throws Exception {
    EntityManager em = null;
    UserTransaction utx = null;
    try {
      em = JPAUtil.getEntityManager();
      utx = JPAUtil.getUserTransaction();
      utx.begin();
      basket = em.merge(basket);
      utx.commit();
      return basket;
    } catch (RuntimeException e) {
      if (utx != null) {
        utx.rollback();
      }
      throw e;
    }
  }

Java Transaction API  (JTA) inside a JEE application
In this example our application is going to make use of an EJB session bean. Unlike in the previous example where our application was controlling the transaction via the UserTransaction class here the container will manage and control the transaction for us. Once again you can download the full source of the ShoppingCartEJBTopLinkJpaPart7.zip file and take a look at what I did.

Using JEE annotations it was very simple to turn the ShoppingManager class into a session bean. The @PersistenceContext annotation was used to obtain an EntityManager instance and you will also notice I got rid of the DAO classes as there really was no need for them anymore as the container manages the transaction.

ShoppingManager.java
@Stateless(name="ShoppingManager")
public class ShoppingManager implements ShoppingService {

  @PersistenceContext(unitName="shopping-cart")
  private EntityManager em;

  public Basket updateBasket(Basket basket) throws ShoppingException {
    try {
      return em.merge(basket);
    } catch (Exception e) {
      logger.error("There was an error updating the basket, exception: " + e);
      throw new ShoppingException("There was an error updating the basket", e);
    }
  }

All these applications were written in Eclipse and tested in a GlassFish 2.0 application server.

Tuesday, September 1, 2009

SEAM - The Shopping Cart Web Application

Seam is ANOTHER web application framework. SIGH. Ok yes sigh another framework to learn but it is not entirely new, if you have been following along with the Shopping Cart tutorials where we used JSF, Facelets, Hibernate, JPA and RichFaces you will see that Seam is not something new just something extra.

This is not a tutorial in Seam more like a brief overview, introduction and comparison. Seam's documentation is pretty good to get started with. They also have sample applications so you can have a look to see how Seam is configured. I have also created a Seam web application based on the Shopping Cart application I did in previous posts. It is an Eclipse project. You will need to download the archived file and import it into your Eclipse workbench. I used JDK 1.6. The download is broken up into two parts simply because the file was too big to store on the server on its own:

  • ShoppingCartSeam.zip - This is the main archive that contains all 4 projects.
  • jboss-embedded-all.jar - A library used to run the embedded JBoss server when running our tests. Once you have imported the ShoppingCartSeam.zip archive into your Eclipse workbench please copy this file to the lib folder of the shopping-cart-test project.


Shopping Cart
I will highlight the major differences between the shopping cart application (that I will call Spring Application) we did in previous tutorials with this Seam shopping cart application.

1. Class diagrams
Below you will be able to compare the class diagram of the Spring application with the class diagram of the Seam application.

Spring class diagram


Seam class diagram


2. Spring vs EJB3
The design of our two applications stays pretty much the same, we still have our 3-tier architecture, i.e.
  • Presentation - GUI
  • Application - Business Logic
  • Data - Database

The difference being:
  • In the Spring application we have loosely coupled our application tier from our presentation tier by using Spring to manage and configure how we use and call our business layered objects. The view package contains all the logic for our GUI and is separated from our business logic. Also we use Spring to manage and configure our transactions.
  • In the Seam application we have tightly coupled our application tier to our presentation tier using Seam annotations and EJB3. There is some debate whether this is good or bad, at the end of the day they both have their advantages and disadvantages and it really depends on the type of project you are working on before deciding on which is better or worse. The Seam application uses an EJB3 session bean.

3. EAR vs WAR
The Spring application was packaged as a WAR as it didn’t have any EJB’s there was no need to create an EAR for it. There were two projects:
  • shopping-cart-web – web application
  • shopping-cart-core – project that contains all our business logic classes. It gets packaged as a JAR file and then added to our web application

Because it is packaged as a WAR we also didn’t need a full blown JEE server to deploy it to so Tomcat did the job quite nicely for us.

The Seam application is packaged as an EAR as it makes use of EJB3’s session beans. The project structure that was created for me when I used JBoss Tools to create a Seam project was the following:
  • shopping-cart – main web app
  • shopping-cart-ear – contains 3rd party libraries as well as datasource resource file used to connect to database
  • shopping-cart-ejb – EJB project that contains all our business logic classes (our entity beans and session beans)
  • shopping-cart-test – a standalone project that contains all our test classes

4. Entity classes
Both projects use the Java Persistence API (JPA) in the Entity classes (Basket, Item and BasketItem) to manage relational data and therefore the Entity classes are the same.

5. Faces Managed Beans
In our Spring application we are using the standard JSF library to manage our beans. We define our managed beans and set properties for it in the faces-config.xml file.

In the Seam application we define our managed beans in the beans class by using a Seam annotation (the annotation is called name and occurs just above the class declaration). Only navigational rules are defined in the faces-config file.

6. Web deployment descriptor
The Seam application has an additional filter and servlet defined in the web deployment descriptor, namely:

<filter>
 <filter-name>Seam Filter</filter-name>
 <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>Seam Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
 <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
<servlet>
 <servlet-name>Seam Resource Servlet</servlet-name>
 <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name>Faces Servlet</servlet-name>
 <url-pattern>*.seam</url-pattern>
</servlet-mapping>
<servlet-mapping>
 <servlet-name>Seam Resource Servlet</servlet-name>
 <url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>

7. JSPX vs XHTML
In the Spring application I created .jspx files for our web pages. I would have preferred to use .xhtml but Eclipse didn’t recognize code completion for me and showed that there were warnings when in actual fact there weren’t. I am sure there is some tweak out there to get rid of the warnings and to include code completion but I couldn’t find it and the hassle was not worth the time spent on it. So instead I used .jspx files which worked nicely for me.

In the Seam application I installed the JBoss Tools plugin for Eclipse and .xhtml files seemed to work fine without any errors.

8. Session vs Conversation
Seam introduces two new contexts, conversation and business process. In the Spring application I define the ShoppingViewHelper class with Session scope in the faces-config.xml file.

I could have done the same with the Seam application (by adding another Seam annotation to my class called Scope and given it a value of Session) instead I opted for the better more manageable context provided by Seam called Conversation context.

9. JUnit vs TestNG
In the Spring application we used the JUnit test framework for all our unit tests.

TestNG is another test framework that works the same as JUnit. TestNG is the default test framework chosen by Seam. You are not restricted to TestNG and can can still use JUnit if you like. You can create unit tests just like we did in the Spring application. Seam allows you to create integration tests quite easily to test a complete process from request to response without too much of an overhead. In order to do this Seam uses an embedded JBoss server. The embedded JBoss server is a lightweight server that only starts up the necessary services required to test your application.

Seam application:

The sample application was a really basic one, there is a lot more to Seam than what I touched on here.

Wednesday, July 15, 2009

Shopping Cart Web Application - Part 8 - Spring

Introduction
The Spring Framework provides solutions to many technical challenges faced by Java developers and organizations wanting to create applications based on the Java platform. Because of the size and complexity of the functionality offered, it can be hard to distinguish the major building blocks from which the framework is composed.

The Spring Framework can be considered as a collection of smaller frameworks. Most of these frameworks are designed to work independently of each other yet provide better functionalities when used together. These frameworks are divided along the building blocks of typical complex applications:

  • Inversion of Control container - configuration of application components and lifecycle management of Java objects.
  • Aspect-oriented programming framework - working with functionalities which cannot be implemented with Java's object-oriented programming capabilities without making sacrifices.
  • Data access framework - working with relational database management systems on the Java platform using JDBC and Object-relational mapping tools providing solutions to technical challenges which are reusable in a multitude of Java-based environments.
  • Transaction management framework - harmonization of various transaction management API's and configurative transaction management orchestration for Java objects.
  • Model-view-controller framework - HTTP and Servlet based framework providing many hooks for extension and customization.
  • Remote Access framework - configurative RPC-style export and import of Java objects over computer networks supporting RMI, CORBA and HTTP-based protocols including web services (SOAP).
  • Authentication and authorization framework - configurative orchestration of authentication and authorization processes supporting many popular and industry-standard standards, protocols, tools and practices via the Spring Security sub-project (formerly Acegi).
  • Remote Management framework - configurative exposure and management of Java objects for local or remote configuration via JMX.
  • Messaging framework - configurative registration of message listener objects for transparent message consumption from message queues via JMS, improvement of message sending over standard JMS API's.
  • Testing framework - support classes for writing unit tests and integration tests.

What you need before we get started

What we will cover
  • Spring and Hibernate
  • Shopping Cart application Spring configuration file
  • Shopping Cart application Data Access Objects
  • Shopping Cart application Web Spring bean configuration file

Level
  • Beginner

The Spring Framework covers a lot of ground and we are only going to scratch the surface. We will add Spring to our Shopping Cart Application and I will show how Spring can be used to make our lives a lot easier. The main goal for this tutorial is to show you how to integrate Spring with Hibernate.

Spring and Hibernate
As learnt in the previous Hibernate tutorial Hibernate is a powerful ORM tool that lies between the Application and the Database. It enables applications to access data from any database in a platform-independent manner. There is no need for the application to depend on the low-level JDBC details like managing connection, dealing with statements and result sets. All the necessary details for accessing a particular data source is easily configurable in xml files.

One of the problems with using Hibernate is that the client application that accesses the database using Hibernate framework has to depend on the Hibernate APIs like Configuration, SessionFactory and Session. These objects will continue to get scattered across the code throughout the application. Moreover, the application code has to manually maintain and manage these objects. In the case of Spring, the business objects can be highly configurable with the help of IOC Container. It is possible to use the Hibernate objects as Spring Beans and they can enjoy all the facilities that Spring provides.

Shopping Cart application Spring configuration file
In Spring, all the business objects are configured in xml files and the configured business objects are called Spring Beans. These Spring Beans are maintained by the IOC which is given to the client application upon request.

1. Hibernate Session Example
In the Hibernate tutorial we created a hibernate.cfg.xml file. In this tutorial we are going to replace this file with a Spring bean configuration file. The Hibernate configuration will be configured in the Spring configuration class as opposed to the hibernate configuration file. The details of the Spring bean configuration file are pasted below:

shoppingcart-database.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  <bean id="shoppingCartDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    <property name="url" value="jdbc:hsqldb:shoppingcart" />
    <property name="username" value="sa" />
    <property name="password" value="" />
  </bean>
  <bean id="shoppingCartSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="shoppingCartDataSource" />
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
        <prop key="show_sql">true</prop>
        <prop key="format_sql">true</prop>
        <prop key="current_session_context_class">thread</prop>
      </props>
    </property>
    <property name="annotatedClasses">
      <list>
        <value>com.mydomain.shoppingcart.bo.Item</value>
        <value>com.mydomain.shoppingcart.bo.Basket</value>
        <value>com.mydomain.shoppingcart.bo.BasketItem</value>
      </list>
    </property>
  </bean>
  <bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
      <ref local="shoppingCartSessionFactory" />
    </property>
  </bean>
  <bean id="basketDao" class="com.mydomain.shoppingcart.dao.impl.BasketDaoImpl">
    <property name="sessionFactory">
      <ref local="shoppingCartSessionFactory" />
    </property>
  </bean>
  <bean id="itemDao" class="com.mydomain.shoppingcart.dao.impl.ItemDaoImpl">
    <property name="sessionFactory">
      <ref local="shoppingCartSessionFactory" />
    </property>
  </bean>
</beans>

1.1. shoppingCartDataSource
The shoppingCartDataSource bean defines a data-source of type 'org.apache.commons.dbcp.BasicDataSource'. More importantly, it defines the various connection properties that are needed for accessing the database. Since we are using HSQL as our database I have specified the hsqldb driver.

1.2. shoppingCartSessionFactory
The shoppingCartSessionFactory bean is responsible for creating Session objects through which Transaction and Data accessing is done. It replaces the session factory configuration we made in the Hibernate tutorial’s hibernate.cfg.xml file. We can also delete the HibernateUtil class we created in the Hibernate tutorial to get a handle on the session factory as Spring is going to do all of that for us.

1.3. transactionManager
The transactionManager bean binds a Hibernate Session from the factory to a thread to support transactions.

1.4. basketDao and itemDao
These last two beans are references to our very own data access objects. I have defined them here to tell Spring to manage the creation of these objects for me and to initialise them with the sessionFactory class.

2. JPA EntityManager Example
In the Hibernate tutorial for the JPA example we created a persistence.xml file. This file stays exactly the same. In this tutorial we are going to add a Spring bean configuration file and tell it that we are using JPA Entity Manager. The details of the Spring bean configuration file are pasted below:

shoppingcart-database.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 
 <bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
  <property name="persistenceUnitName" value="shopping-cart" />
 </bean>
 
 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory">
   <ref local="entityManagerFactory" />
  </property>
 </bean>
 <bean
  class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
 
 <bean id="basketDao" class="com.mydomain.shoppingcart.dao.impl.BasketDaoImpl">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
 </bean>
 
 <bean id="itemDao" class="com.mydomain.shoppingcart.dao.impl.ItemDaoImpl">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
 </bean>
 
 <tx:annotation-driven />
</beans>

2.1. entityManagerFactory
The entityManagerFactory is a FactoryBean that creates a JPA EntityManagerFactory according to JPA's standard standalone bootstrap contract.

2.2. transactionManager
The transactionManager bean is a PlatformTransactionManager implementation for a single JPA EntityManagerFactory used to support transactions.


2.3. basketDao and itemDao
Like in the Hibernate example I have defined the DAO classes. They both extend the Spring JJpaDaoSupport helper class.

Shopping Cart application Data Access Objects

1. Hibernate Session Example
As you know we have two DAO implementations, BasketDaoImpl and ItemDaoImpl. We configured these classes already in our Spring bean configuration file so we know that Spring is going to manage the creation and initialisation of these classes for us. I have also made sure these classes both extend Springs HibernateDaoSupport class. The HibernateDaoSupport class is a convenient super class for Hibernate-based data access objects. It requires a SessionFactory to be set, providing a HibernateTemplate based on it to subclasses through the getHibernateTemplate() method.

BasketDaoImpl.java
@Transactional
public class BasketDaoImpl extends HibernateDaoSupport implements BasketDao {

    public void delete(final Basket basket) throws Exception {
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Object basketObj = session.load(Basket.class, basket.getId());
                session.delete(basketObj);
                return null;
            }
        };
        getHibernateTemplate().execute(callback);
    }

    public void saveOrUpdateBasket(final Basket basket) throws Exception {
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                session.saveOrUpdate(basket);
                return null;
            }
        };
        getHibernateTemplate().execute(callback);
    }

    public Basket removeItemFromBasket(final BasketItem basketItem) throws Exception {
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {

                Basket basket = (Basket) session.load(Basket.class, basketItem.getBasket().getId());
                for (Iterator<BasketItem> it = basket.getBasketItems().iterator(); it.hasNext();) {
                    BasketItem existingBasketItem = (BasketItem) it.next();
                    if (existingBasketItem.getId().equals(basketItem.getId())) {
                        if (existingBasketItem.getQuantity() > 1) {
                            existingBasketItem.decreaseQuantity();
                        } else {
                            it.remove();
                        }
                    }
                }
                session.saveOrUpdate(basket);
                return basket;
            }
        };
        return (Basket) getHibernateTemplate().execute(callback);
    }
}

I will step through the saveOrUpdateBasket method only as the others are very similar. The first thing you will notice is the instantiation of an anonymous class from a Spring interface called HibernateCallback.

There is one method inside this class called doInHibernate. This method will be called by the HibernateTemplate’s execute method. An active Hibernate session is passed to this method. As you can see we don’t care about activating or closing the Session, or handling transactions. This is all taken care of by Spring.

2. JPA Entity Manager Example
The BasketDaoImpl class in the JPA sample application extends Springs helper class (JpaDaoSupport):

BasketDaoImpl.java
@Transactional
public class BasketDaoImpl extends JpaDaoSupport implements BasketDao {

    public void delete(Basket basket) throws Exception {
        basket = getJpaTemplate().find(Basket.class, basket.getId());
        getJpaTemplate().remove(basket);
    }

    public Basket update(Basket basket) throws Exception {
        return getJpaTemplate().merge(basket);
    }
    
    public Basket removeItemFromBasket(BasketItem basketItem) throws Exception {
        Basket basket = getJpaTemplate().find(Basket.class, basketItem.getBasket().getId());
        for (Iterator<BasketItem> it = basket.getBasketItems().iterator(); it.hasNext(); ) {
            BasketItem existingBasketItem = (BasketItem) it.next();
            if (existingBasketItem.getId().equals(basketItem.getId())) {
                if (existingBasketItem.getQuantity() > 1) {
                    existingBasketItem.decreaseQuantity();
                } else {
                    it.remove();
                }
            }
        };
        return getJpaTemplate().merge(basket);
    }
}

Shopping Cart application Web Spring bean configuration file
I created a Spring bean configuration file for the web project as well. The main reason for this was so that I would let Spring manage the creation and retrieval of our ShoppingManager service. I created a file called applicationContext.xml and saved it in the WebContent/WEB-INF directory.

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 <bean id="shoppingService" class="com.mydomain.shoppingcart.service.impl.ShoppingManager">
  <property name="itemDao">
   <ref bean="itemDao" />
  </property>
  <property name="basketDao">
   <ref bean="basketDao" />
  </property>
 </bean>
 <import resource="classpath:shoppingcart-database.xml" />
</beans>

Sunday, July 5, 2009

Shopping Cart Web Application - Part 7 - Hibernate


Introduction
Hibernate is an object-relational mapping (ORM) library for the Java language, providing a framework for mapping an object-oriented domain model to a traditional relational database.
If you are new to Hibernate I would suggest reading the documentation on the Hibernate website as well as this tutorial.

What you need before we get started


What we will cover

  • Hibernate Overview
  • Java Persistence API
  • Shopping cart web application changes


Level
  • Beginner

Overview
Hibernate's primary feature is mapping from Java classes to database tables (and from Java data types to SQL data types). Hibernate also provides data query and retrieval facilities. Hibernate generates the SQL calls and relieves the developer from manual result set handling and object conversion, keeping the application portable to all supported SQL databases, with database portability delivered at very little performance overhead.

Java Persistence API
The Java Persistence API (JPA) provides an object/relational mapping facility to Java developers for managing relational data in Java applications. Java Persistence consists of three areas:
  • The Java Persistence API
  • The query language
  • Object/relational mapping metadata

JPA was introduced in JEE 5 and forms part of the JSR 220 EJB3.0 specification. The Java Persistence API draws upon the best ideas from persistence technologies such as Hibernate, TopLink, and JDO. Customers now no longer face the choice between incompatible non-standard persistence models for object/relational mapping.

Both sample applications use JPA annotations in the Entity classes, the difference between the two is in the data access objects. The Hibernate sample application makes use of Hibernate's session factory to read and write to the database whereas the JPA sample application makes use of JPA's EntityManager to read and write to the database.  

For further reading and information on JPA I recommend these links:

Shopping Cart Web Application


Database Schema
Below is a schema of the database I want my application to use:



The SQL statements for the creation of these tables for this database will look like:
create table basket (id bigint not null unique, primary key (id)) ENGINE=InnoDB;
create table basket_item (id bigint not null unique, price double precision not null, quantity integer not null, items_id bigint not null, basket_id bigint not null, primary key (id)) ENGINE=InnoDB;
create table item (id bigint not null unique, description varchar(255), name varchar(255) not null, price double precision not null, primary key (id)) ENGINE=InnoDB;
alter table basket_item add index FK3F6FA5ECF59CCC6 (basket_id), add constraint FK3F6FA5ECF59CCC6 foreign key (basket_id) references basket (id);
alter table basket_item add index FK3F6FA5EC98F3A8D9 (items_id), add constraint FK3F6FA5EC98F3A8D9 foreign key (items_id) references item (id);

The above basket table is pretty useless but I wanted an example which had a many-to-one association with items. The basket table could also include more columns such as username.

HSQLDB
HSQLDB (Hyperthreaded Structured Query Language Database) is a relational database management system written in Java. The reason I have chosen this database over MySQL or any other database is because I wanted an in-memory database so that it would be easier for readers who are unfamiliar with configuring databases to get my sample application up and running without much hassle. Using HSQLDB’s in-memory database all I had to do was include the HSQLDB library in my applications classpath. Hibernate will create the database for me and prepopulate our database with necessary data.

Hibernate configuration file vs Persistence configuration file
The Hibernate sample application requires a Hibernate configuration file whereas the JPA sample application requires a persistence configuration file. Both are very similar:

1. Hibernate configuration file
Hibernate uses a file (hibernate.cfg.xml) to configure hibernate properties such as connection details to the database, location of the entity classes used to create tables in the database and a whole range of other settings. This is a copy of the hibernate.cfg.xml we used in the Shopping Cart application:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="hibernate.connection.url">jdbc:hsqldb:shoppingcart</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="current_session_context_class">thread</property>
        
        <mapping class="com.mydomain.shoppingcart.bo.Item" />
        <mapping class="com.mydomain.shoppingcart.bo.Basket" />
        <mapping class="com.mydomain.shoppingcart.bo.BasketItem" />
    </session-factory>
</hibernate-configuration>

2. Persistence configuration file
Much like the Hibernate configuration file the persistence configuration file is used to configure the JPA context.
<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_1_0.xsd"
 version="1.0">
 <persistence-unit name="shopping-cart" transaction-type="RESOURCE_LOCAL">
  <properties>
   <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
   <property name="hibernate.connection.url" value="jdbc:hsqldb:shoppingcart" />
   <property name="hibernate.connection.username" value="sa" />
   <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
   <property name="hibernate.archive.autodetection" value="class" />
   <property name="hibernate.show_sql" value="true" />
   <property name="hibernate.format_sql" value="true" />
  </properties>
 </persistence-unit>
</persistence>


Annotations
Many APIs require a fair amount of boilerplate code (any code that is or can be reused in new contexts or applications without being changed much from the original). For example, in order to write a JAX-RPC web service, you must provide a paired interface and implementation. This boilerplate could be generated automatically by a tool if the program were “decorated” with annotations indicating which methods were remotely accessible.

Annotations are like meta-tags that you can add to your code and apply them to package declarations, type declarations, constructors, methods, fields, parameters, and variables. As a result, you will have helpful ways to indicate whether your methods are dependent on other methods, whether they are incomplete, whether your classes have references to other classes, and so on.

Annotation-based development relieves Java developers from the pain of cumbersome configuration. Annotation-based development lets us avoid writing boilerplate code under many circumstances by enabling tools to generate it from annotations in the source code. This leads to a declarative programming style where the programmer says what should be done and tools emit the code to do it.

Mapping with EJB3/JPA Annotations
Every bound persistent POJO class is an entity bean and is declared using the @Entity annotation (at the class level). Below is an extract of the code of what our Item class now looks like having annotations added to it:

Item.java
@Entity
@Table(name="item")
public class Item implements Serializable  {
 private static final long serialVersionUID = 1135428828106917172L;
 private String description;
 private Long id;
 private String name;
 private Double price;
 private List<BasketItem> basketItems = new ArrayList<BasketItem>(0);
 
 public Item() {
 }

 public Item(Long id, String name, double price) {
  this.id = id;
  this.name = name;
  this.price = price;
 }

 public Item(Long id, String description, String name, double price) {
  this.id = id;
  this.description = description;
  this.name = name;
  this.price = price;
 }
 
 @Column(name="description")
 public String getDescription() {
  return description;
 }

 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 public Long getId() {
  return id;
 }

 @Column(name="name", nullable=false)
 public String getName() {
  return name;
 }

 @Column(name="price", nullable=false, precision=22, scale=0)
 public Double getPrice() {
  return price;
 }

 public void setDescription(String description) {
  this.description = description;
 }

 public void setId(Long id) {
  this.id = id;
 }

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

 public void setPrice(Double price) {
  this.price = price;
 }
 
 @OneToMany(mappedBy="item", cascade=CascadeType.ALL)
 public List<BasketItem> getBasketItems() {
  return this.basketItems;
 }

 public void setBasketItems(List<BasketItem> basketItems) {
  this.basketItems = basketItems;
 }
}


  • @Entity declares the class as an entity bean (i.e. a persistent POJO class). @Id declares the identifier property of this entity bean. The other mapping declarations are implicit.
  • @Table is set at the class level; it allows you to define the table, catalog, and schema names for your entity bean mapping. If no @Table is defined the default values are used: the unqualified class name of the entity.


Hibernate Annotation Extensions
Hibernate 3.1 offers a variety of additional annotations that you can mix/match with your EJB 3 (JPA) entities. They have been designed as a natural extension of JPA annotations. I am using a Hibernate annotation in the Basket class to handle the removal of orphans as the current version of JPA doesn't have an annotation that handles this.

Basket.java
@OneToMany(mappedBy="basket", cascade=CascadeType.ALL)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
public List<BasketItem> getBasketItems() {
 return basketItems;
}

To empower the EJB3 capabilities, hibernate provides specific annotations that match hibernate features. The org.hibernate.annotations package contains all these annotations extensions. Please refer to the hibernate documentation for more information.

Serializable
One of the other important things to note was that our entity classes implement the interface Serializable. Strictly speaking, this is not a requirement. However, in practice you will normally want your Hibernate objects to be serializable so that they can be (potentially) migrated around a multiprocessor cluster or saved and restored across a web server reboot etc.

Session Factory vs EntityManager
The Session factory is used by the Hibernate sample application to transact with the database whereas the EntityManager is used by the JPA sample application.

1. SessionFactory
The session factory creates Sessions. Usually an application has a single SessionFactory. Threads servicing client requests obtain Sessions from the factory. The Session interface is the main runtime interface between a Java application and Hibernate. The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes.

2. EntityManager
An EntityManager instance is associated with a persistence context. The EntityManager is used to create and remove persistent entity instances, to find entities by their primary key, and to query over entities.


Hibernate utility class vs JPA utility class
I created a utility class that will be used by any class within the Shopping Cart application that requires a hibernate session / EntityManager.

1. Hibernate utility
The class is called HibernateUtil.java and can be found in the com.mydomain.shoppingcart.util package.

2. JPA utility
The class is called JPAUtil.java and can be found in the com.mydomain.shoppingcart.util package.


Data Access Object (DAO's)
A Data Access Object (DAO) is an object that provides an abstract interface to some type of database or persistence mechanism, providing some specific operations without exposing details of the database. The DAO pattern allows data access mechanisms to change independently of the code that uses the data. Compare the DAO's in the Hibernate sample application to the JPA sample application. You will see where the Hibernate session is being used and where JPA's EntityManager is being used. I created two DAO's, one for each of our Entities:
  • ItemDaoImpl – implements ItemDao interface
  • BasketDaoImpl – implements BasketDao interface

Lastly I tied the rest of the pieces together so that our application was using our DAO's now and not just getting back stubbed data.