As we saw earlier, with every hibernate session, a persistence context is associated. This context is aware of all the persistent objects that are associated with the hibernate session. The objects are maintained in maps with the identifier as the primary key. Hibernate very smartly uses this data to perform some query optimization.
Consider the below code that retrieves record from the database.
As a result, the session is now working as a cache of database objects. This cache works across transactions. As sessions are associated with a single thread we do not encounter any concurrency issues.
As every record is there only once in a session, any circular references (possible in bidirectional associations) do not lead to a stack overflow.
Consider the below code that retrieves record from the database.
public static void testFetch() { Session session = sessionFactory.openSession(); System.out.println("Fetching the object via load call"); Entity entity1 = (Entity) session.load(Entity.class, 1);
String data = entity1.getData(); System.out.println("Fetching the object via get call"); Entity entity2 = (Entity) session.load(Entity.class, 1); System.out.println("Objects are equal ? " + entity2.equals(entity1)); session.close(); }The output for the equals check is
Fetching the object via load call 2984 [main] DEBUG org.hibernate.event.def.DefaultLoadEventListener - loading en tity: [com.model.Entity#1] ... Fetching the object via get call 2984 [main] DEBUG org.hibernate.event.def.DefaultLoadEventListener - loading en tity: [com.model.Entity#1] 2984 [main] DEBUG org.hibernate.event.def.DefaultLoadEventListener - entity pro xy found in session cache ... Objects are equal ? trueFrom the logs we can also see that the select query was executed only once.
2625 [main] DEBUG org.hibernate.SQL - select entity0_.id as id0_0_, entity0_.DATA as DATA0_0_ from Entity entity0_ where entity0_.id=?Also the equals method returned true. This tells us two things:
- For any record in the database only a single representation is present in Hibernate session.
- If the record is already present in Hibernate session, the object is not fetched again, it is simply used from the persistence context.
public static void testFetch() { Session session = sessionFactory.openSession(); System.out.println("Fetching the object via load call"); Entity entity1 = (Entity) session.load(Entity.class, 1); String data = entity1.getData(); System.out.println("Fetching the object via query call"); Query q = session.createQuery("from Entity e where e.id = ?"); q.setInteger(0, 1); Entity entity2 = (Entity) q.uniqueResult(); System.out.println("Objects are equal ? " + entity2.equals(entity1)); session.close(); }For the query Hibernate reads the id from the result-set and tries to resolve this object in the persistence cache.Only if the record is not found thus Hibernate load the remaining data from the result-set.Thus before loading any object, Hibernate checks if the object is already present in the session. If it finds it in the persistence context it avoids the data fetch, instead returning the object in the persistence context.
As a result, the session is now working as a cache of database objects. This cache works across transactions. As sessions are associated with a single thread we do not encounter any concurrency issues.
As every record is there only once in a session, any circular references (possible in bidirectional associations) do not lead to a stack overflow.
This comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete