EJB 3.0 : Java Persistence API [ JPA ]
- What is JPA ( Java Persistence API )?
- Object-Relational Mapping (ORM)
- Introduction to Entity
- Entity Manager API
- Life Cycle of Entity
- Entity Listeners and Callbacks
- Packaging a persistence unit
- Obtaining an Entity Manager
- Example for JPA
What is JPA ( Java Persistence API )? |
- Java Persistence API (JPA) provides POJO (Plain Old Java Object ) standard and Object Relational Mapping (ORM) for the persistent data among the applications.
- The Persistence deals with the storing and Retrieving the application data, and now can be programmed with JPA introduced in EJB 3.0.
- The term persistence data refers to the permanent data in an application which can be retained permanently by storing in persistent medium like relational database. In JPA, persistent data termed as entities.
- The entity serves as a logical collection of the data that needs to be stored or retrieved.
JPA Scenario
- For Example, in an online book Purchasing application, the book and the person buying the book are treated as entities.
- The person’s name, credit card details, his address etc. are logically grouped together to represent an entity person.
- Similarly, ISBN number, book name and author name for entity Book.
- In technical term, entity is a POJO with the use of simple annotation.
- Entities are the focus of JPA
- The unique features of entities include their persistence and transaction abilities, and their identity.
- PersonID would serve as the identity for the Person entity or the primary key for the person table. So, Entity Person can be uniquely identified by PersonID.
- JPA focuses on entities and Object Relational Mapping (ORM).
- ORM is a programming technique which helps in mapping java object provided in the java class with the relational database columns or rows or tables.
Object-Relational Mapping (ORM) |
Object-Relational Mapping (ORM)
- Java Objects can store the data in the relational database by using RDBMS.
- For this, We divide the java database object into different components and store each part separately.
- So, The mapping of java objects into a relational database is termed as ORM. The java objects are saved into the tables available in the database.
- The configuration metadata reports to the high level API about the tables in which the sets of objects are going to be stored.
- The Configuration metadata also determines the particular rows and columns in which the objects are going to be stored.
- The configuration metadata in EJB 3.0 consists of annotations, deployment descriptor elements or both.
- The mapping of entity into ORM is done by using annotations, such as @Table, @Column, @Enumerated, @Lob. Since these annotations are used to map an entity into an ORM
Introduction to Entity |
Introduction to Entity
- Entities are the Persistent java Objects used to store data in a database.
- The Persistent data refers to the permanent data in an application.
- Entities store data as fields and also have associated methods.
- All the information regarding an entity is always available in ORM.
- Entities support relational and object oriented capabilities, such as entities, inheritance and polymorphism.
- The Client does not communicate directly with the relational database.
- The web browser accesses the JSP page present in the web container. Then JSP page calls the appropriate entity bean, and java objects of the entity bean class holds the data provided by the client in the JSP Page.
- These java Object, with the help of the EJB Container, stores the data in the relational database within mapped tables.
More on Entity with EJB 2.x Vs EJB 3.0
- The EJB 3.0 has made the programming simpler and makes the container do more work than the developers.
- EJB 2.x provides two types of entity beans, i.e. CMP and BMP. But here this is not the case.
The introduction of the new JPA has remodeled and reshaped the concept of entity bean in EJB 3.0. - So, To understand how entity beans are created in EJB 3.0, let us first learn to introduce Plain Java Class and then later convert it into an entity with the help of annotations.
Advanced features, such as inheritance, polymorphism and complex relations are not available in EJB 2.x.
POJO (Plain Old Java Object)
Among the business components, those Java objects that do not implement any special interfaces or invoke any framework APIs are called POJOs
- POJOs
- offer decoupling
- simplify development
- provide better separation of design concerns
- offer improved portability
- make testing easier
package javaskool.example;
public class Employee implements java.io.Serializable{
private int employeeID;
private boolean permanent;
public int getEmployeeID(){
return employeeID;
}
public boolean isPermanent(){
return permanent;
}
public void setEmployeeID(int employeeID){
this.employeeID = employeeID;
}
public void setPermanent(boolean isPermanent){
this.permanent = permanent;
}
}
▴ Properties▴ Getter ▴ Setter
To Make POJA as Entity
- To Make the Plain Old java Class an entity, annotations such as @Entity, @Table, @Column, @ID etc . are used.
- Apart from these annotations, JPQL is also used to query with the database.
- Moreover, the instance of the EntityManager is created to manage the entity.
Entity Manager API |
Entity Manager API
- The EntityManager API is most important part of the Java Persistent API (JPA).
- It is an interface specifically used to access entities in the application’s persistent context.
- All the entities available in the persistent context must be unique and can be identified by the primary key associated with the entities.
- EntityManager API manage the life cycle of entities.
- The EntityManager API is the connecting bridge between object oriented data and relational database.
- EntityManger deletes the entity from the persistent context, when the request is to delete the entity.
- when the request is to update the entity, then the EntityManger looks at the relational database which corrsponds to the entity and updates it.
- Similarly, when request is to save an entity in the persistent context, then the EntityManager creates an entity object and maps this object to the relational database and returns the entity object back to the object oriented world.
Entity Manager
- EntityManager interface is divided in two different interfaces, known as the container-managed and the application-managed.
- Container-managed Entity Manager :- in this, The container runtime provides the EntityManager for an application. The container injects the EntityManager with the @PersistentContext annotation. Otherwise, the lookup() method is used to obtain the EntityManager from the PersitentContext.
- Application-managed Entity Manager :- In this, the application itself is responsible to creating the EntityManager for itself.
Life Cycle of Entity |
Life Cycle of Entity
The Life Cycle of an entity is managed by the EntityManger API. It provides the method for entity like, new(), remove(), find(), persist() etc.
The Entity life cycle consists of four different stages:
- New : At this stage , a new entity instance is created that is not associated with any persistent identity or persistent context.
- Managed : At this stage , the entity has persistent identity in the database and is associated with persistent context. An entity is said to be in the managed state after the persist() method is called. Changes to the entity are synchronized in the database after the transaction is committed or the flush() method is called.
- Detached : At this stage , the entity has its persistent identity but is no longer associated with any persistent context.
- Removed : At this stage , the entity is currently associated with the persistent context but it is ready to be removed from the database.
Entity Listeners and Callbacks |
Entity Listeners and Callbacks
It is often useful fro the application to react to certain events which occur inside the persistence mechanism. This allows the implementation of certain kinds of generic functionality, and extension of built-in functionality.
EJB 3 Specification provides two related mechanism
- The First mechanism is that the method of the entity may be designed as the callback method to receive the notification of the particular entity life-cycle events. The Callback methods are annotated using callback annotations.
- The Second mechanism is to define the entity listener class to be used instead of the callback methods defined directly inside the entity class.
Entity Listeners
An Entity Listener is a stateless class with no argument constructor. An Entity listener is defined by annotating the entity class with @EntityListeners annotations. We can define several entity listeners per entity within different levels of hierarchy but can’t define two listeners for the same event in the same entity.
Can be defined by three ways:
- @EntityListeners : The listener specifies the callback listener classes that are to be used for an entity.
- @ExcludeSuperclassListeners : This listener specifies the invocation of the super calss listeners, that is to be executed for the entity. Here the listener will also be executed for the sub class.
-
@ExcludeDefaultListeners : This listener specifies the invocation of the default listeners which is to be executed for the entity class. The listener is to be excluded for both the super class and the subclass.
Callbacks
Callbacks are generally the methdos of entities used to receive notification about a specific entity.
The JPA specification defines the following life-cycle events for an entity:
- PrePersist : This is represented by the @PrePersist annotation. It is synchronous with the persist operation and executed before entity manger persist operation is actually executed.
- PostPersist: This is represented by the @PostPersist annotation. It is executed after the database persist operation is executed. It is called after the insert operation.
- PreRemove : This is represented by the @PreRemove annotation. It is synchronous with the database remove operation and executed before entity manger remove method is actually executed.
- PostRemove : This is represented by the @PostRemove annotation. It is executed after entity manger remove operation is actually executed. It is synchronous with the remove operation.
- PreUpdate : This is represented by the @PreUpdate annotation. It is executed before the database update operation.
- PostUpdate : This is represented by the @PostUpdate annotation. It is executed after the database update operation.
- PostLoad : This is represented by the @PostLoad annotation. It is executed after an entity is loaded into the persistent context or the entity is being refreshed.
Packaging a persistence unit |
Packaging a persistence unit
The J2EE application consists of one or more entities. These entities are packaged in a persistence unit. In Simpler words, the entities are not limited to the EJB modules, rather, they are packaged in a web module, EAR module, or the standard jar file.
These entities are packaged in a descriptor called 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="persist123" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jta4anujcust</jta-data-source>
<mapping-file></mapping-file>
<jar-file></jar-file>
<class>javaskool.Customer</class>
</persistence-unit>
</persistence>
Obtaining an Entity Manager |
Obtaining an Entity Manager
- The Entity Manager in EJB 3.0 acts as a path for the client to acquire the entity manager services offered by EJB3.0 persistence framework. The Client sessions must have an entity manger instance for interacting with the entities. It helps in Querying, updating, removing, and refreshing the entity instances.
- Entity Manager maintains a collection of the instances within the transaction context called persistence context.
- The client can access or update the entity data as they would be the Plain Old Java Objects.
- The EntityManager can be obtained from both within the EJB Container or outside it.
- The Client can obtain an Entity Manager instance by using the Container Injection or by using the EntityManagerFactory or by looking up the EntityManger thru JNDI.
Obtaining an Entity Manager thru Session Bean Using the Container Injection
The session bean uses the container injection to obtain an EntityManager instance which is bound to a persistent unit.
@Stateless
Public class Customer
{
@PersitenceContext("persistence")
Private EntityManager em;
Public void createCustomer()
{
final Customer cust=new Customer();
cust.setName("abc");
em.persist(cust);
}
}
Obtaining an Entity Manager Using EntityManagerFactory
Sometimes the application desires more control over the life cycle of the Entity Manager. Then the client has a better option for obtaining the instance of an entity manger by an EntityManagerFactory. The javax.persistence.Persistence class acts as a factory to acquire the EntityManagerFactory.
public static void main(String a[])
{
final EntityManagerFactory emf=Persistence.createEntityManagerFactory("persistence");
final EntityManger em=emf.createEntityManager();
final Customer cust=new Customer();
cust.setName("abc");
em.persist(cust);
}
Obtaining an Entity Manager by looking up using JNDI
The EntityManagerFactory or the EntityManger, lookup with the help of the java Naming Directory Interface (JNDI).
EntityManger em=(EntityManager)ctx.lookup("xyz");
Different way to create EntityManager Object
- There are important differences between the injected EntityManager, and the EntityManager created from an injected EntityManagerFactory. Basically, injected EntityManager is container-managed, meaning all of its lifecycle is controlled by the container (web container or EJB container). Application code cannot close it, or otherwise interfere with its life.
- In addition, for a container-managed EntityManager, its associated PersistenceContext is automatically propagated along with the underlying JTA, from servlet A to servlet B, from servlet to EJB, from EJB a to EJB B, and so on. As such, EntityManager of the same configuration injected into various classes can share the same PersistenceContext in a call stack.
- On the other hand, EntityManager created from EntityManagerFactory is application-managed EntityManager. Application code is responsible for managing its whole lifecycle. And there is no PersistenceContext propagation for application-managed EntityManager.
- Are all EntityManager’s obtained from EntityManagerFactory application-managed EntityManager? Yes.
- Is it possible to get a container-managed EntityManager from EntityManagerFactory? No.
- You may have read about the method EntityManagerFactory.getEntityManager(), which returns a container-managed EntityManager. This method was considered and included in the early draft version of Java Persistence API, but was eventually removed from its final release.
Example for JPA |
Click Here to Download the Code
Java Persistence API ( JPA) without EJB Container mean application-managed only
META-INF/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="zzz" transaction-type="RESOURCE_LOCAL">
<!-- using default provider-->
<!--<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>-->
<class>com.javaskool.Customer</class>
<properties>
<property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/db1"/>
<property name="toplink.jdbc.user" value="root"/>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="toplink.jdbc.password" value="admin"/>
<!--<property name="toplink.ddl-generation" value="drop-and-create-tables"/> -->
<property name="toplink.ddl-generation" value="create-tables"/>
<property name="toplink.jdbc.read-connections.max" value="1"/>
<property name="toplink.jdbc.read-connections.min" value="1"/>
<property name="toplink.jdbc.write-connections.max" value="1"/>
<property name="toplink.jdbc.write-connections.min" value="1"/>
</properties>
</persistence-unit>
</persistence>
Customer.java
package com.javaskool;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import java.sql.Date;
@Entity
public class Customer
{
@Id
int customerId;
String name;
int age;
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public int getCustomerId() {
return this.customerId;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
JPADemo1.java
package com.javaskool;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.io.*;
public class JPADemo1
{
public static void main(String[] args)
{
EntityManagerFactory emf=Persistence.createEntityManagerFactory("zzz");
EntityManager em=emf.createEntityManager();
try
{
EntityTransaction et=em.getTransaction();
et.begin();
Customer cc=new Customer();
DataInputStream d=new DataInputStream(System.in);
System.out.println("Enter CID : ");
int cid=Integer.parseInt(d.readLine());
System.out.println("Enter Name: ");
String cname=d.readLine();
System.out.println("Enter Age : ");
int cage=Integer.parseInt(d.readLine());
cc.setCustomerId(cid);
cc.setName(cname);
cc.setAge(cage);
em.persist(cc);
et.commit();
Query query=em.createQuery("select c1 from Customer c1");
List rs=query.getResultList();
int size=rs.size();
System.out.println("CID \t Name \t Age" );
System.out.println("====\t =====\t ====");
for(int i=0;i<size;i++)
{
Customer c=(Customer)rs.get(i);
System.out.println(c.getCustomerId()+"\t"+c.getName()+"\t"+c.getAge());
}
}
catch(Exception e){System.out.println(e);}
finally
{
if(em != null){em.close();}
}
}
}
It is truly a nice and helpful piece of info. I’m glad that you shared this helpful information with us.Please stay us informed like this. Thank you for sharing.