Saturday 27 April 2013

What is JPA, It's advantage and Implementation



What is JPA?

JPA Stands for Java Persistence API. It’s a specification provided by SUN Microsystems, released under JEE5 specification. JPA was defined as part of the EJB 3.0 specification and worked as a replacement for the EJB 2 CMP Entity Beans specification. Directly, JPA can’t be used for persistence. Persistence, means which deals with storing and retrieving of application data. It needs an ORM implementation to persist the java objects into DB. Hibernate, Toplink, iBatis, Open JPA etc. ORM frameworks can be used with JPA.  JPA is the latest of several Java persistence specifications. The biggest benefit of JPA is that it is independent API and easily integrates with J2EE and J2SE.

Note: - OpenJPA is an open source implementation of the JPA specification. It’s an ORM solution, which simplifies storing objects in databases. It is open source provided by Apache Software Foundation.

Advantage of Using JPA:-

  • Supported by many ORM frameworks

  • Providing independent API

  • Easy to use API and it can directly deal with POJO’s

  • Providing a standard specification

  • Many implementation are available in the market

  • Supports both XML and annotation based configuration.


 Sample code for JPA implementation:-

STEPS:-

1) Create a java project in eclipse and name it as JPAImplementaionUsingAnnotations.

2) Create a package in the src folder and name it as com.gaurav.jpaannotations.

3) Create a java file and name it as customer. place the below source code in that file.

4) The list of required jars for the successful execution of this project is as below:-
     antlr-2.7.6
     commons-collections-3.1
     dom4j-1.6.1
     hibernate3
     hibernate-jpa-2.0-api-1.0.0.Final
     javassist-3.12.0.GA
     jta-1.1
     mysql-connector-java-5.1.14-bin
     slf4j-api-1.6.1


Customer.java

package com.gaurav.jpaannotations;

import javax.persistence.Column;

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

@Entity
@Table(name = "customer")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column
    private String name;

    @Column
    private String password;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Customer) {
            Customer user = (Customer) obj;
            return user.getId() == this.getId();
        }

        return false;
    }
}

4) Create a file persistence.xml inside src/META-INF folder and place the below source code in that file.

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.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_2_0.xsd">

    <persistence-unit name="JPAAnnotations" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <class>com.gaurav.jpaannotations.Customer</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
             <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

5) Create a java file in the package com.gaurav.jpaannotations under src folder and name it as JPAClient .
place the below source code in that file.

JPAClient.java

package com.gaurav.jpaannotations;


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

public class JPAClient {

    /**
     * This is the main method(), where I am calling all the CRUD operation methods.
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPAAnnotations");
        EntityManager em = emf.createEntityManager();

        try {
            saveDataUsingJPA(em);
            findDataUsingJPA(em);
            updateDataUsingJPA(em);
            removeDataUsingJPA(em);
        }
        finally{
            emf.close();
        }
       
    }
   
    /**
     * This method is responsible for saving data in the table.
     */
    public static void saveDataUsingJPA(EntityManager em){
         try {
             em.getTransaction().begin();
 
             Customer cust = new Customer();
             cust.setName("Shivam");
             cust.setPassword("bighome");
 
             em.persist(cust);
 
             em.getTransaction().commit();
         }
         catch (Exception e) {
             em.getTransaction().rollback();
             e.printStackTrace();
         }
         System.out.println("#####     Data is inserted properly     #####");
        
    }
   
    /**
     * This method is responsible for finding/searching data in the table.
     */
   
    public static void findDataUsingJPA(EntityManager em){
        try {
            em.getTransaction().begin();

            Customer cust = em.find(Customer.class, 1);

            System.out.println("Customer Name:-"+cust.getName());
            System.out.println("Customer Password:-"+cust.getPassword());
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        System.out.println("*****     Data Retrieval Completed Successfully     *****");
    }
   
    /**
     * This method is responsible for updating data in the table.
     */
   
    public static void updateDataUsingJPA(EntityManager em){
        try {
            em.getTransaction().begin();

            Customer cust = em.find(Customer.class, 3);

            cust.setName("Mihika");
            cust.setPassword("password");

            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        System.out.println("@@@@@     Data Updation Completed Successfully     @@@@@");
    }
   
    /**
     * This method is responsible for removing data in the table.
     */
   
    public static void removeDataUsingJPA(EntityManager em){
        try {
            em.getTransaction().begin();

            Customer cust = em.find(Customer.class, 4);

            em.remove(cust);

            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        System.out.println("~~~~~     Data removal Completed Successfully     ~~~~~");
    }
}

The project directory structure is as follows:-


Note:- I have placed all the referenced library inside Latest-Hibernate-Jars-4JPA-Annotations folder which is in JPAImplementaionUsingAnnotations(in the project). 

Records available in the table  before the program execution is as follows:-

Note:- As hibernate will create a table automatically if we are using hibernate.hbm2ddl.auto in the configuration file. But in the above program i am invoking update and remove operations on different records which is not available at the first time. That's why i have inserted the records manually before the execution of program.

Result:-


After the successful execution of the above program the records available in the table is as below:-



JPA related terms:-



  • An EntityManager represents a PersistenceContext i.e. essentially a cache. A Cache is just a copy of data, here the copy means pulled from DB and alive outside the DB.

  • An EntityManagerFactory is responsible to create an EntityManager.


With <persistence-unit transaction-type="RESOURCE_LOCAL">
We must use the EntityManagerFactory to get an EntityManager instance. The resulting EntityManager instance is a PersistenceContext/Cache. Invoking entityManagerFactory.createEntityManager() creates two separate EntityManager instances and therefor two separate PersistenceContexts/Caches. It’s a bad habit to have more than one instance of an EntityManager in use if we want then we should destroy the first.

No comments:

Post a Comment