Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate 3.6 - session.get() vs session.load()

I am trying to understand what the difference is in returned object and behavior of Hibernate 3.6 session.get() and session.load().

From the javadoc:

get():

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

load():

Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists. This method might return a proxied instance that is initialized on-demand, when a non-identifier method is accessed.

I have three questions:

  1. The javadoc does not say when load() might return a proxy - is there any way to know it in advance?

  2. When load() returns a proxy - this means load() did not access the database, am I correct? Then what if I provided load() with an identifier that does not exist in the database? I will now have in the session a proxy with an invalid ID (without getting an Exception). Now I want to let another persistent instance point to that proxy - is it going to work? For this scenario I do not need to initialize the proxy, I only need its id (which I have even though its invalid since it's not in the database). So I guess I am asking if my description is correct, and do I always need to check out after load() the returned object with isInitialized() in order to make sure it represents a valid entity (or at least a valid proxy), i.e. with a valid ID.

  3. Also, what happens if load() returns a proxy - so the proxy is the instance that is already associated with the session. Then according to the description of get(): "If the instance is already associated with the session, return that instance." - so does get() return the proxy? Since according to the description of get(): "This method never returns an uninitialized instance."

Thanks!

UPDATE

Are the following correct?

(A) I think both load() and get() will first try to check the session cache before going to the DB - so it would not be right to say that any of them always hits the DB, or always returns a proxy.

(B) An initialized proxy is not the same as the original instance, as you can read here: http://blog.xebia.com/2008/03/08/advanced-hibernate-proxy-pitfalls/

like image 202
rapt Avatar asked Nov 08 '11 01:11

rapt


People also ask

What is the difference between the hibernate Session get () and load () method?

In hibernate, get() and load() are two methods which is used to fetch data for the given identifier. They both belong to Hibernate session class. Get() method return null, If no row is available in the session cache or the database for the given identifier whereas load() method throws object not found exception.

What is the difference between load () and get ()?

Get() returns the object by fetching it from database or from hibernate cache whereas load() just returns the reference of an object that might not actually exists, it loads the data from database or cache only when you access other properties of the object.

Which statement is correct about Session Load () in hibernate?

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.

What is the default return type of Session get () method in hibernate?

get() returns the object by fetching it from database or from hibernate cache. when we use get() to retrieve data that doesn't exists, it returns null, because it try to load the data as soon as it's called.


1 Answers

(1) , (3) :

Yes. You are right .Both the load() and get() will first check if there is an instance with the same PK is persisted in the session.

If yes , just returns that instance from the session. (It may be the proxy or the actual entity class instance)

If no , load() will create and return a proxy while get() will hit DB and returns instance of the actual entity class .

The returned object from both methods will be associated and persisted in the session afterwards.

So , whether get() or load() return proxy or the actual entity class depends on whether you use get() or load() to get the instance of the same PK in the current session for the first time.

You can proof this behaviour by performing the following test:

Session session = HibernateUtil.getSessionFactory().openSession();

Item loadItem= (Item ) session.load(Item.class, 1);
System.out.println(loadItem.getClass().getName());

Item getItem = (Item ) session.get(Item .class, 1);
System.out.println(getItem .getClass().getName());

If it is an proxy , the printed class name will not be the same as the actual entity class name. Just change the execution order of to load() and get() to see the effect.

(2):

If load() returns a proxy , it will not access the DB during load() .The proxy will only accesses the DB if their mapped properties besides the PK are accessed and there are no instances with the same PK value is associated with the session.

After the proxy accesses the DB , the instance with the same PK of the proxy will be associated with that session .So when you get another properties from the proxy again or you use get() to get the instance for the same PK , the DB will not be accessed as the values can be found from the session.

For example:

/**Session starts***/
Item item = (Item) session.load(Item.class, new Long(1));
item.getId();  //Will not access DB as only the identifier property is access
item.getDescription(); // access the DB and initialize the proxy . After that , the item proxy is said to be initialized
item.getPrice(); //will not access DB as the item with the PK 1 can be get from the session
Item item2 = session.get(Item.class, new Long(1)) //will not access DB as the item with the PK 1 can be get from the session

If you load() an instance with the invalid ID and then access the properties or call a method (such as isInitialized()) on this proxy , ObjectNotFoundException will be thrown. So if you can catch ObjectNotFoundException , it means a proxy is loaded with an invalid ID.

If you want to ensure the ID is valid during the runtime , you should use get() and check if the returned instance is null . load() is useful when setting the foreign key constraint. See this

like image 78
Ken Chan Avatar answered Oct 29 '22 14:10

Ken Chan