Main Tutorials

Different between session.get() and session.load()

Often times, you will notice Hibernate developers mix use of session.get() and session load(), do you wonder what’s the different and when you should use either of it?

Different between 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. Let’s go through some examples to understand in what situation you should use session.load().

1. session.get()

For example, in a Stock application , Stock and StockTransactions should have a “one-to-many” relationship, when you want to save a stock transaction, it’s common to declared something like below

           
    	   Stock stock = (Stock)session.get(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);        
           session.save(stockTransactions);

Output


Hibernate: 
    select ... from mkyong.stock stock0_ 
    where stock0_.STOCK_ID=?
Hibernate: 
    insert into mkyong.stock_transaction (...) 
    values (?, ?, ?, ?, ?, ?)

In session.get(), Hibernate will hit the database to retrieve the Stock object and put it as a reference to StockTransaction. However, this save process is extremely high demand, there may be thousand or million transactions per hour, do you think is this necessary to hit the database to retrieve the Stock object everything save a stock transaction record? After all you just need the Stock’s Id as a reference to StockTransaction.

2. session.load()

In above scenario, session.load() will be your good solution, let’s see the example,

           
    	   Stock stock = (Stock)session.load(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);        
           session.save(stockTransactions);

Output


Hibernate: 
    insert into mkyong.stock_transaction (...) 
    values (?, ?, ?, ?, ?, ?)

In session.load(), Hibernate will not hit the database (no select statement in output) to retrieve the Stock object, it will return a Stock proxy object – a fake object with given identify value. In this scenario, a proxy object is enough for to save a stock transaction record.

Exception

In exception case, see the examples

session.load()


Stock stock = (Stock)session.load(Stock.class, new Integer(100)); //proxy

 //initialize proxy, no row for id 100, throw ObjectNotFoundException
System.out.println(stock.getStockCode());

It will always return a proxy object with the given identity value, even the identity value is not exists in database. However, when you try to initialize a proxy by retrieve it’s properties from database, it will hit the database with select statement. If no row is found, a ObjectNotFoundException will throw.


org.hibernate.ObjectNotFoundException: No row with the given identifier exists: 
[com.mkyong.common.Stock#100]

session.get()


//return null if not found
Stock stock = (Stock)session.get(Stock.class, new Integer(100)); 
System.out.println(stock.getStockCode()); //java.lang.NullPointerException

It will always return null , if the identity value is not found in database.

Conclusion

There are no always correct solution, you have to understand the differential in between, and decide which method is best fix in your application.

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
24 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
John DeRegnaucourt
12 years ago

Session.load() will return a proxy always and it will *not* throw the ObjectNotFoundException exception until later (on access). This is a key point missed in the discussion above. Because it does not throw the ObjectNotFoundException until it is accessed, it can make tracking errors harder.

Session.get() will return the proxied object with one-level loaded (the fields for the object with the given identifier) plus cascading. If the object with the given ID does not exists, you will know right then because it will return null, not a proxy.

The thing to keep in mind (imho) is when do you want to find out if the object with the given id exists or not? If you need to know right away, use get(). If it is OK to find out later, then use load().

Saitej
9 years ago

Good explanation………………

Lluis
6 years ago

>session.get()
> It always hit the database and return the real object, an object that represent the database row, not proxy.

False. Javadoc says: Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance is already associated with the session, return that instance. This method never returns an uninitialized instance.)

It will hit the database just once. Subsequent calls with the same id will return the cached instance.

Bittu
6 years ago

Thank you ses.load is really useful in one to many bi directional association performance wise only one object is created

WTF
9 years ago

Documentation for hibernate fectching stretegy says,
the results of get(),load(),save(), saveorUpdate(),merge() are always cached in the first level cache. that means the same session by default. OR we could make them cacheable using the secondary cache.
As per my understading, there are two points.

1) if you are using the first level cache (session cache) which is the default one. Take the same stock example from the tutorial and consider a senario where one user has to do some transaction. The first step ofcourse would be to login. Once the user login, the user object would be cached using a get() method . The next time user wants to save a transaction, it is better to use the load() coz the user object is already in the cache. i dont consider here any patterns like session per tranasaction or session per conversation.

2) if the secondary cache is enabled. It means the cache is global to a particular SessionFactory object. As a probabilty, we can say there are concurrently 100 users who want to check the current stock for a particular company. Now we would just use a load() method to try and load the object from the cache coz there is a strong probabilty, some on before me would have checked the stock.

Mallikarjuna
4 years ago

Difference between eagerloading and lazy loading

arun singh
5 years ago

I checked it using “show_sql” in the console that get() method did not fire SELECT query when the object was already available in the cache, it means it does not always hit the database.
But I see this statement that it always hits the database in most tutorials. Don’t know what’s the truth.

van
6 years ago

Get method provides the implementation of eager loading, whereas load() method provides the implementation of lazy loading.

arun singh
6 years ago

helpful

ARUN
7 years ago

Hi
May i know which class having the implementation of session.load(); actually session is an interface on that we will define the methods only not implementation of load() right .where i see that implementation ,otherwise how load method create a proxy object internally you give simple implementation example of how load method create proxy obj internally.
.

Tara Prasad Dash
8 years ago

Thanks dude… as always simple and to the point explanation. Hats off.

Avinash Ga
8 years ago

Excellent….. Thanks Mkyong.

Giri
9 years ago

As per my understanding the Load() looks for the data initially in Cache, but if it didn’t find match then it hits the DB.
while Get() always hits the DB directly.

sarty
9 years ago

i am also having the same doubt??how without hitting DB its getting data?

prakash
9 years ago

I run both load and get in both cases select query is printed.i think its wrong written here

Tin
9 years ago

Hi mkyong,

You’ve got a great website. It has been helpful to me so many times. I did few test run to see how get() and load() works. They seem very similar to me (the only difference I can think of is that one throws exception and another one returns null). Both of them work without having an entry in the database as long as there is a persist object in the session. So “always hit the database” seems not quite right. I may be wrong. I’m quite new to Hibernate.

ankur
10 years ago

Great explanation… Thank a lot

Ganga
10 years ago

Good explanation.

Paulo_Italiano
10 years ago

Good explanation, thanks mkyong!

Muskaan
10 years ago

Thank you mkyong,

I have one doubt. Load() and get() methods accepts only primary key value in parameter, if we haven’t primary key value, and we want to retrieve by other value we commonly used HQL. what is the difference between using HQL, it his a database or else;

Lokesh
10 years ago

Thanks a lot Mkyong for such a clear explanation.

anilkumar
10 years ago

Nice explanation

zazuge
14 years ago

well that’s the official definition
but i got a strange thing
when i tried to retrieve and fully initialized instance with:
session.get(MyClass.class, proxied_instance.getId());
but get seem to return the same proxied instance and not a fully initialized instance 🙁