Monday, June 22, 2009

Difference between get & load in hibernate

In this post, we will look into the main difference between load method & get method in hibernate session.
Order order = (Order)session.get(Order.class, 1L);
When the above line is executed within the same session then we will end up in only one database query. ie. for first time before executing query, Order object with id = 1 will be searched in the session. If it finds the object then there wont be database hit to get order object with identity 1. Hence calling the get method twice or more with identity 1 in same session will end up with only one database hit. Moreover if the order object with id = 1 is not find in the session or database then order will be null.
Order order = (Order)session.load(Order.class, 1L);
The load method will never hit the database instead it will try to fetch an order object with identity = 1 from the session cache and if it finds the object then the same will return else it will create an proxy object with identity = 1 and return to the caller. Hence how many times we call the above line in the same session, it will end up in creating only one order object with identity 1. When we try to access the property of order object then there will be dataase hit to fecth an order object. If there is no order object with id =1 then we will end up with Object Not Found Exception. If we are trying to access an order object for first time outside the session then we will end up with Lazy Initialization Exception. We should use get method for checking the object existence. If we are very sure that we will not access the property and the order object with id =1 is available in database then we can use the load method to create a proxy and the same object can be attached to any object, where the association is required to persist the object with relationship.
Order order = (Order)session.createQuery("from Order where id = 1").uniqueResult();

The number of times the above query executed the same number of database hits will be. Even though the order object with = 1 is available in session, it will not be fetched from session cache. But, the order object will be synched in such a way that only one order object with id =1 will be available in the session.


Session sess = factory.openSession();
Transaction tx;
 try {
     tx = sess.beginTransaction();
     //DB hit to fetch Order object with id =1
     Order order1 = (Order)session.get(Order.class, 1L);
     //Fetched from session cache, no DB hit
     Order order2 = (Order)session.get(Order.class, 1L);
     //Return true
     System.out.println(order1.equals(order2));
     //Return true
     System.out.println(order1 == order2);
     //No DB hit, display the order description
     System.out.println(order1.getDescription());
     System.out.println(order2.getDescription());
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }

Session sess = factory.openSession();
Transaction tx;
 try {
     tx = sess.beginTransaction();
     //Create a proxy of order object with id =1 
     Order order1 = (Order)session.load(Order.class, 1L);
     //Fetched proxy from session cache
     Order order2 = (Order)session.load(Order.class, 1L);
     //Return true
     System.out.println(order1.equals(order2));
     //Return true
     System.out.println(order1 == order2);
     //DB hit to display the order description
     System.out.println(order1.getDescription());
     //No DB hit
     System.out.println(order2.getDescription());
     //Create a proxy of order object with id =-1 
     Order order3 = (Order)session.load(Order.class, -1L);
     //Fetched proxy from session cache
     Order order4 = (Order)session.load(Order.class, 1L);
     //Return true
     System.out.println(order3.equals(order4));
     //Return true
     System.out.println(order3 == order4);
     //DB hit to display the order description, since it is invaild id... throws
     //ObjectNotFoundException
     System.out.println(order3.getDescription());
     //Will not reach here
     System.out.println(order2.getDescription());
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }

Followers