Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Wednesday, 22 October 2014

Hibernate Entity / Persistence LifeCycle States

As you know that Hibernate works with normal Java objects that your application creates with the new operator. In raw form (without annotations), hibernate will not be able to identify your java classes, but when they are properly annotated with required annotations then hibernate will be able to identify them and then work with them e.g. store in DB, update them etc. These objects can be said to mapped with hibernate.

Given an instance of an object that is mapped to Hibernate, it can be in any one of four different states: transient, persistent, detached or removed.

Transient Object

Transient objects exist in heap memory. Hibernate does not manage transient objects or persist changes to transient objects.
Transient objects are independent of Hibernate
Transient objects are independent of Hibernate
To persist the changes to a transient object, you would have to ask the session to save the transient object to the database, at which point Hibernate assigns the object an identifier and marks the object as being in persistent state.

Persistent Object

Persistent objects exist in the database, and Hibernate manages the persistence for persistent objects.
Persistent objects are maintained by Hibernate
Persistent objects are maintained by Hibernate
If fields or properties change on a persistent object, Hibernate will keep the database representation up to date when the application marks the changes as to be committed.

Detached Object

Detached objects have a representation in the database, but changes to the object will not be reflected in the database, and vice-versa. This temporary separation of the object and the database is shown in image below.
Detached objects exist in the database but are not maintained by Hibernate
Detached objects exist in the database but are not maintained by Hibernate
A detached object can be created by closing the session that it was associated with, or by evicting it from the session with a call to the session’s evict() method.
In order to persist changes made to a detached object, the application must reattach it to a valid Hibernate session. A detached instance can be associated with a new Hibernate session when your application calls one of the load, refresh, merge, update(), or save() methods on the new session with a reference to the detached object. After the call, the detached object would be a persistent object managed by the new Hibernate session.

Removed Object

Removed objects are objects that are being managed by Hibernate (persistent objects, in other words) that have been passed to the session’s remove() method. When the application marks the changes held in the session as to be committed, the entries in the database that correspond to removed objects are deleted.

Key Points

  1. Newly created POJO object will be in the transient state. Transient object doesn’t represent any row of the database i.e. not associated with any session object. It’s plain simple java object.
  2. Persistent object represent one row of the database and always associated with some unique hibernate session. Changes to persistent objects are tracked by hibernate and are saved into database when commit call happen.
  3. Detached objects are those who were once persistent in past, and now they are no longer persistent. To persist changes done in detached objects, you must reattach them to hibernate session.
  4. Removed objects are persistent objects that have been passed to the session’s remove() method and soon will be deleted as soon as changes held in the session will be committed to database.

Tuesday, 21 October 2014

Hibernate - How to fix “identifier of an instance altered from X to Y”?

Problem :- Getting the error ” identifier of an instance of com.sample.SampleAltered from 1 to 1″

Solution :- Check whether the java type of the identifier field in the Data Object, the type of the field in the hibernate xml file and the type of the column in the database are compatible types or not.

Explanation :-
This problem will occure only when you have an mismatch of data type between your bean-hibername xml mapping & database table column datatype.

For Example,

class SampleAltered{

long sampleId;
String sampleName;


public int getSampleId(){
….
}

public void setSampleId(int i){
…..
}

}

And this was the hbm file declaration

<class name="com.sample.SampleAltered" table="sample_data">
   <id name=”sampleId” type=”int” column=”sample_id”>
       <generator class=”native” />
   </id>
   <property name=”sampleName” type=”string” column=”sample_name” length=”50″/>
</class>


In above example if you note, class SampleAltered was having sampleId with datatype long & hbm xml file contains the entry for same with datatype int.

Whenever you are trying to do database transaction with above mapping you will get the error of "identifier of an instance altered from X to Y".

To fix this issue you need to change datatype of sampleId either in hbm mapping file or in class.

Thursday, 3 July 2014

Hibernate session.get() and session.load()

Actually, both functions are use to retrieve an object with different mechanism, of course.

1. session.load()
It will always return a “proxy” (Hibernate term) without hitting the database. In Hibernate, proxy is an object with the given identifier value, its properties are not initialized yet, it just look like a temporary fake object.
If no row found , it will throws an ObjectNotFoundException.


2. session.get()
It always hit the database and return the real object, an object that represent the database row, not proxy.
If no row found , it return null.
It’s about performance

Hibernate create anything for some reasons, when you do the association, it’s normal to obtain retrieve an object (persistent instance) from database and assign it as a reference to another object, just to maintain the relationship.

Thursday, 19 June 2014

What is a query cache in Hibernate?

The query cache is responsible for caching the results and to be more precise the keys of the objects returned by queries. Let us have a look how Hibernate uses the query cache to retrieve objects. In order to make use of the query cache we have to modify the person loading example as follows.

Query query = session.createQuery("from Person as p where p.parent.id=? and p.firstName=?");
query.setInt(0, Integer.valueOf(1));
query.setString(1, "Joey");
query.setCacheable(true); //caches the query
List l = query.list();


You also have to change the hibernate configuration to enable the query cache. This is done by adding the following line to the Hibernate configuration.

<property name="hibernate.cache.use_query_cache">true</property>


Note that the query cache does not cache the state of the actual entities in the result set. It caches only identifier values and results of value type. So the query cache should always be used in conjunction with the second-level cache.

This is an optional feature and requires two additional physical cache regions that hold the cached query results and the timestamps when a table was last updated. This is only useful for queries that are run frequently with the same parameters.