Showing posts with label JPA. Show all posts
Showing posts with label JPA. Show all posts

Wednesday, December 30, 2015

Entity States

Java applications contain a mix of transient and persistent objects. Transient (or normal objects) has a limited lifetime and is bounded by life of the process that instantiated it.  But persistent objects (or Entity) can be stored on disk or file system to create again in the future. 

The Java Persistence API (JPA) is part of EJB 3.0 specification (EJB 3.0 itself is part of Java Enterprise Edition). JPA refers to persisted or persistable  classes as Entity.  Technically, it's  just a POJO class which maps to a database table/view. Instance of an entity can represent a single row of a table. This post will cover different states an instance of an Entity could be in. In context of JPA, object and entity refers to the same thing (more details here)

Entity States 

  1. New/Transient Object which got instantiated using new operator is in transient state as it's not yet associated with any persistence context. It's not mapped yet to a record/row in database. It's just another object; and in fact JPA specification doesn't give any name for this state. 
  2. Managed/Persistent Object has a database identity. This means the instance has a valid primary key value to uniquely identity it in the database (or more specifically in a table). These instances are associated with a persistence context. 
  3. Detached As long as persistence context is active entity is in managed state. Once transaction (or unit of work) completes, persistence context is closed but the application still has handle to the entity. So such entities are in detached state. 
  4. Removed During the transaction we can delete or remove an entity. It's still associated with persistence context but it get's scheduled for deletion (at the end of transaction). So a removed object shouldn'd be reused and any reference holding it should be discarded. 
Image Reference : http://openjpa.apache.org

Let's Code

Let's code to explain the above states:

New

Student student = new EngineeringStudent();
student.setName(..);
student.setGrade(..);
student.setXX(..);

Managed

entityManager.persist(student);    //JPA
session.save(student);                  //Hibernate 

Delete
session.delete(student);
entityManager.remove(student);

Detached
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

Student student = fetchStudentWithIdFromDb(id);
student.setGrade(..);
tx.commit();
session.close();

student.setXX(..);   //student is detached here

Detaching Inside a transaction
session.evict(student);  //detaches one object
session.clear(); //detaches all objects

Monday, June 8, 2015

Brief overview of JPA

JPA(Java Persistence API) came into the picture to bring object-oriented and relational model together. It's basically an abstraction on top of JDBC (and is part of EJB 3.0 specification); to let you deal with tables without using SQL. Before this, the persistence model of Java was called as Entity Bean and was part of Enterprise Java Beans specification. Entity Bean wasn't lightweight, and hence got replaced by this new (new age) API.

Relational databases store data in tables in form of rows and columns. So dealing with tables directly was not very convenient in Java where objects rule. JDBC bridged the gap a bit but wasn't able to remove SQL altogether. JPA consists of two broad components to solve the full problem - first is the mapping of objects to tables and second is providing the ability to query. Let's cover them briefly:

Mapping (ORM): JPA maps Java objects to relational database tables. Mapping is achieved through ORM metadata. The metadata describes the mapping between table and objects (and attributes and columns). It was initially achieved by a descriptor XML file, but it got further simplified and now annotations are preferred approach (Use of annotations brought convention over configuration technique). So, just put annotations at Class, field/method level and boy you are done with mapping.

A common confusion is that hand-coded SQL queries are going to be as fast as one automated by ORM tool or maybe even better. So is it recommended to use ORM tools?

Yeah, it's safe to assume that hand-coded SQL/JDBC can be easily analyzed and optimized. But, ORM tools like Hibernate gives much more optimizations like automated queries and caching out of the box. It hides a lot many details and allows the programmers to focus on core business problems. Also, these tools abstract your underlying database as well. 

Querying: Mapping will not make much sense if we still have to write SQL queries so JPA tweaked SQL to come up with its own query language, JPQL(Java Persistence Query Language). JPQL queries entity objects.  JPQL doesn't understand underlying row/columns and tables, it queries objects so uses familiar notation i.e. dot (.). 

Evolution of JPA

JPA 1.0 (May 2006, EJB 3.0) brought the object-oriented and relational model together. It was bundled as part of J2EE 1.3 and then later J2EE 1.4 as well.

JPA 2.0 (Dec 2009, Java EE 6) It extended JPQL, added second-level cache, pessimistic locking (criterial API)

JPA 2.1(Apr 2013, Java EE 7) supports schema generation (persistance.xml), converters, CDI, stored procedures, bulk update and delete queries, enhanced criteria API (update and delete)
more here - http://www.thoughts-on-java.org/jpa-21-overview/

* From version 5, J2EE is known as Java EE, and similarly J2SE is know as Java SE.


Entity

Objects which get persisted through JPA provider(like hibernate) is referred to as Entity. Entities live shortly in memory and persistently in a database. So you basically perform all operations on Entity which are POJO and it typically represents a row of a table. Entity class should satisfy below conditions:
  • Entity class must be annotated with @javax.persistance.Entity
  • The class must have public or protected no arg constructor (it can have other constructors as well)
  • The class must not be declared as final. No method or persistent instance variable must be declared as final
  • The class must not be enum or interface 
  • If the instance has to be passed by value as the detached object, the entity class must implement Serializable interface
@Entity
public class Employee{..}

@Entity annotation converts the Employee class into an entity (in above snippet).  Also going by convention over configuration rule, the table name is same as class name (i.e. Employee).


JPA Frameworks/Implementation

  • Hibernate open source implementation, supports JPA from version 3.2, influenced JPA specification
  • TopLink commercial implementation
  • Java Data Objects (JDO)
  • EclipseLink also supports object XML mapping. Reference implementation of JPA. 

Note: Persistence provider or provider refers to JPA implementation.