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 the Author

author image
mkyong
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

avatar
24 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
23 Comment authors
MallikarjunavanBittuarun singhLluis Recent comment authors
newest oldest most voted
Lluis
Guest
Lluis

>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.

John DeRegnaucourt
Guest
John DeRegnaucourt

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… Read more »

Saitej
Guest
Saitej

Good explanation………………

Bittu
Guest
Bittu

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

Mallikarjuna
Guest
Mallikarjuna

Difference between eagerloading and lazy loading

arun singh
Guest
arun singh

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
Guest
van

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

arun singh
Guest
arun singh

helpful

ARUN
Guest
ARUN

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
Guest
Tara Prasad Dash

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

Avinash Ga
Guest
Avinash Ga

Excellent….. Thanks Mkyong.

WTF
Guest
WTF

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… Read more »

Giri
Guest
Giri

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
Guest
sarty

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

prakash
Guest
prakash

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

Tin
Guest
Tin

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
Guest
ankur

Great explanation… Thank a lot

Ganga
Guest
Ganga

Good explanation.

Paulo_Italiano
Guest
Paulo_Italiano

Good explanation, thanks mkyong!

Muskaan
Guest
Muskaan

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
Guest
Lokesh

Thanks a lot Mkyong for such a clear explanation.

anilkumar
Guest
anilkumar

Nice explanation

trackback
DAO, Hibernate & DBUnit « core dump

[…] there is one last bit that I need to add. The difference between Session.get() and Session.load(). This is a good account of its usage and […]

trackback
Hibernate Tutorials | J2EE Web Development Tutorials

[…] Different between session.get() and session.load() Understanding when should use get or load to retrieve the object in order to avoid unnecessary hit to the database. […]

zazuge
Guest
zazuge

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 :(