Saturday 19 October 2013

[Java] Hibernate 4 object states

In order to manage objects representing rows in database tables, the user of Hibernate needs to have a grasp of object states within the framework. This tutorial will be an introduction for first-timers to the notion of object states in Hibernate. I assume that you are able to make and run a basic Hibernate example, otherwise please read the first tutorial "Hello Hibernate 4 with Eclipse Kepler" (http://peace-and-code.blogspot.com/2013
/10/java-hello-hibernate-4-with-eclipse.html
).
The version of Hibernate we will use is 4.2.5 (http://sourceforge.net/projects/hibernate/files/hibernate4/4.2.
5.Final/
).
In the rest of this tutorial, we will refer to classes mapped to actual database tables as entities, and to the subsequent objects representing rows in these tables as entity instances.


1. Hibernate object states

Actually, from Hibernate's point of view, an entity instance is either:
  1. irrelevant to the database as it has never been attached to a Session object, and this category consists of Transient objects;
  2. relevant to the database, and that is true if the entity has been attached to a Session obejct at least once. This category includes exclusively two types of objects: Persistent and Detached objects.
Officially, Hibernate defines 3 object states:
  • Transient: this is an entity instance that have never been attached to a Session object.
  • Persistent: it is an entity instance which is:
    • associated to a row in the database so that the modifications performed on this entity instance are reflected on the row;
    • attached to a Session object by the possible means of attachment;
    • inside the scope to the session to which this instance is associated.
  • Detached: this is an entity instance which:
    • has been Persistent then its session was closed;
    • hasn't been reattached to a Session object since it lost its Persistent state;
    • modifications will be reflected on the associated row once it regains its Persistent state.


2. Transition between states


Hibernate defines a set of transitions between these 3 states (see figure):
  • From Transient to Persistent: by attaching the entity instance to a Session object. Pass the Transient object to one of following methods to turn it Persistent, persist[1], save[2], saveOrUpdate[3] or merge[4]. Objects returned by calling one of the following methods are automatically Persistent, load[5], get[6] and createQuery[7].
  • From Persistent to Detached: by closing the session to which this entity is attached (close[8]).
  • From Detached to Persistent: by reattaching the entity instance to a new Session object by the means of update[9], saveOrUpdate[3], merge[4], lock[10] or replicate[11]. Note that if you intend to reattach a Detached object to a new session, you need to make sure that no other entity instance sharing the same row is associated with this session.
  • From Persistent to Transient: by breaking the association between the entity instance and its session. Perform a delete[12] and commit(session.getTransaction().commit()[13]) to turn a Persistent object into Transient state.
  • From Detached to Transient: by deleting the entity instance inside the scope of a new Session object.


3. Examples

The listing below is the practical counterpart of the theoretical explanation in the two first parts of this tutorial. To effectively monitor the attachment state of your entity instances, use the contains[14] method within the session scope.

Happy Hibernate object state transitions!

---
External links:

[1] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#persist%28java.lang.Object%29
[2] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#save%28java.lang.Object%29
[3] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#saveOrUpdate%28java.lang.Object%29
[4] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#merge%28java.lang.Object%29
[5] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#load%28java.lang.Class,%20java.io.Serializable%29
[6] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#get%28java.lang.Class,%20java.io.Serializable%29
[7] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/SharedSessionContract.html#createQuery%28java.lang.String%29
[8] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#close%28%29
[9] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#update%28java.lang.Object%29
[10] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#lock%28java.lang.Object,%20org.hibernate.LockMode%29
[11] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#replicate%28java.lang.Object,%20org.hibernate.ReplicationMode%29
[12] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#delete%28java.lang.Object%29
[13] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Transaction.html#commit%28%29
[14] http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Session.html#contains%28java.lang.Object%29

1 comment: