Tuesday, May 19, 2009

Hibernate session.get () Vs session.load ()

Subscribe in a reader


In my recent assignment, we had a requirement to fetch a single row from DB (i.e. entity) using Hibernate framework. So Session.get(Class clazz, Serializable id) straightaway came into my mind. However

there is one more function named Session.load(Class theClass, Serializable id) to achieve same functionality.


Since both functions are part of Session interface, there has to be some difference between each of them. Let's see their usage and differences.



Sesion.get( Class theClass, Serializable id) throws HibernateException

It returns persistent instance of the given entity class with the given identifier. Incase of non-existence it will return null.


So to get an entity from the underlying persistence store, all you have to do is call Hibernate Session’s get method and provide two arguments: Java class associated with the entity that you are retrieving which in our case would be User.class and actual primary key associated with the record. i.e.


session.beginTransaction();
User user = (User)session.get(User.class, new Long(1));
System.out.println(user.getPassword());
session.getTransaction().commit();

In above code, I have simply retrieved an instance of User class using get () and then printing “password” property before transaction commit.


Now same code, instead of get () I will use load () as below. Before that let me explain definition of session.load ()


public Object load(Class theClass, Serializable id) throws HibernateException returns persistent instance or proxy of a class with the given identifier. We can not use this method to determine if an instance is exists. In case of non-existence of the instance it will throw an exception.

session.beginTransaction();
User user = (User)session.load(User.class, new Long(1));
System.out.println(user.getPassword());
session.getTransaction().commit();


I have shown code snippet for both methods, now let’s concentrate on real part and that is comparison between these two methods.

Well if you were to compare the load and the get method of Hibernate Session, it looked pretty similar, and you’d be correct. However there are subtle and importance differences.


First of all, the Get method hits Database as soon as it is called. So this method will always trigger a DB hit. While load method will hit the database when particular field is accessed (i.e. user.getPassword ()) so if you use load method to retrieve an entity, but you never actually access any field of the entity, it never hits the database. I think this is pretty good.



Well, actually, as per above description, load method might sound good, but it triggers more problems then it solvesL. Let’s understand WHY?


When you initialize java bean (i.e. entity) from the load method, you can only access the properties of the java bean, for the first time, with in transactional context in which it was initialized.


When you try to access various properties outside of the transactional context that has been already committed, you will get LazyInitializationException, as hibernate no longer has valid transactional context to use and hit the database.


So below code will fail and throw LazyInitializationException – Could not initialize proxy – no session


session.beginTransaction();
User user=(User)session.load(User.class, new Long(1));
session.getTransaction().commit();
System.out.println(user.getPassword());

So, big thing to understand from the load method is, you can’t really use loaded JavaBean after the transaction is committed, whereas, you can use get method, because all the properties of the JavaBean has been initialized right away

Now let’s us talk about one more difference. What happens when you provide a primary key that doesn’t exists in the database? Well, with the get method, it will simply return null object, which is no big deal, I can simply put a null check in my DAO class method.


But with the load method, again it will not create any problem when you an invalid primary key. Does that mean, it will return a null object or what? Well, the answer is simply NO. You will run into problem when you try to access a property of that instance.

So after comparing load and get methods, you will ask when to use load ()? And when to use get ()? Let’s see….

Use get (

  • If you ever want to use JavaBean properties even after transaction has been committed. And quite frankly, that tends to be most of the time. For example, if you load a User instance in a Servlet, and you want to pass that instance to a Java Server Page for display purposes, you'd need to use the get method, otherwise, you'd have a LazyInitializationException in your JSP
  • If you are not sure that entity with the given primary key is exists or not

Use load ()

  • If your goal is transactional and you want to access JavaBean properties with in the specified transaction
  • If you want to ensure that JavaBean is sync with the database, you will use load method. Because it will ensure that fields are loaded in from the database and not from the JVM on which you are running
  • If you are absolutely sure that the entity you are searching is already present in database.

I hope above explanation will help you to understand differences between both functions and their actual usage.

With good understanding of these two functions will surely help you in avoiding LazyInitializationException

Subscribe in Reader