简体   繁体   中英

Hibernate: session.load vs session.get

I was under the impression that session.load() loads the proxy object in the cache while session.get() always hits the database but I am confused after watching a JavaBrains video .

According to this video when we are calling the below get method it is loading the proxy object of UserDetails in the memory.

user = (UserDetails) session.get(UserDetails.class, 1); 

Structure of UserDetails is

在此处输入图片说明

While in the comment section, a guy commented:

there is no proxy of User class, instead the proxy object of the collection is created.

Now there are two questions here.

1st: Related to fetching strategies and creation of proxy objects in case of session.load() and session.get() which has been answered below by me.

2nd: In this case, the proxy object will create for UserDetails or for collection (still to be answered).

Thanks

1.Fetching Strategies: There is no effect of fetching strategies in the working of session.get or session.load ( https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch20.html#performance-fetching-lazy ).

2. Session.get: It never returns proxy , As per the hibernate docs : ( https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html#get(java.lang.Class , java.io.Serializable))

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

Means get method first check the cache if the fully initialize object is present there if yes return that object otherwise it hits the database to get the object and returns the same after saving it in the cache space.

3. Session.load: As per the hibernate docs :

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.

Means load method first check the cache if the fully initialize object is present there and if yes returns that object else it returns the proxy(A proxy is a class that delegates to another object. Initially, when it's not initialized, it contains just the primary key. When you call a method, as the Javadoc says, it initializes, by loading the actual entity from the database, and the delegates to this loaded entity) of that object by `assuming that instance exists'.

Note: Important to note that load method never throw an exception .You will get ObjectNotFoundException in case you try to retrieve any other property instead of the primary key from the proxy object.As it will hit the database to load the object from there, which is not exists.

Here, UserDetails is the parent and Address is the child. Hibernate is actually lazy-loading the child Address . So eventually all children elements ( Address in this case) are not pre-loaded while you load the parent ( UserDetails in this case).

So, when you do this:

user = (UserDetails) session.get(UserDetails.class, 1); 

Hibernate is not actually loading all the child ( Collection<Address> ). Instead Hibernate load Address only when you explicitly access them. So Hibernate won't hit DB for Address table unless you really need them and that's the purpose of lazy loading .

What it means by Lazy loading is that while you get a proxy object of UserDetails , it doesn't really hit the Address table unless you try to access Collection elements explicitly. In other words, you need to iterate over the collection for Hibernate to fetch Address table.

You could end yourself into a situation where you hit the database everytime for each child ( Address ). So, make a explicit call listOfAddresses.size() so as to load all children at a time.

Also note that Lazy loading will happen by default for One-To-Many and Many-To-Many cases.

2 Ques Ans : Proxy will be of Address for your question context you can say that. In depth or detail ,first hibernate will create proxy for userdetail also but as soon as query hit that proxy will have data. But as hibernate by default is lazy loading and Address is a child in UserDetail, it will be return as a proxy only and you will get only the id value of Address(primary key value). Don't get confused about proxy. Proxy will be created for all class either parent class(UserDetail) or child class(Address), but for child class it will only have id data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM