<div dir="ltr" style="text-align: justify;">
<div dir="ltr" style="text-align: justify;">
<div dir="ltr" style="text-align: justify;">
<div dir="ltr" style="text-align: justify;">
<div style="color: blue;">In this tutorial we look what is proxy object and how hibernate provide the proxy object for us and also we look about some fetching strategies.</div>
<div id="ads-id" align="center"></div>
<div style="color: blue;">So we first look about the proxy object.</div>
<div></div>
<h2 style="color: #20124d;"><b>Hibernate Proxy Object:</b></h2>
<div style="color: #20124d;">An object proxy is just a way to avoid retrieving an object until you need it.</div>
<div style="color: #20124d;"></div>
<div style="color: #20124d;">In our example user class has the three field values-</div>
<div style="color: #20124d;"><b>1. User Id </b></div>
<div style="color: #20124d;"><b>2. User Name</b></div>
<div style="color: #20124d;"><b>3. List of the Addresses</b></div>
<div style="color: #20124d;"></div>
<div style="color: #20124d;">
<p>If you want retrieve user object from the database, so what field value are retrieved from the database and which field are initialized. Suppose one user XYZ has the 100 addresses in the database and we want to retrieved the name of this user from database. For that we retrieve the user object, now question is this what about the field <b>listOfAddress</b> field, Is it also have the value? if you say yes so what about cost of memory ? if you say no so how to retrieve the value associated with that field the address table in the database on demand.</p>
<pre>-A 
 | 
 *---B 
 | | 
 | *---C 
 | | 
 | *---D 
 | | 
 | *---E 
 | | 
 | *---F 
 | | 
 | *---G 
 *---H</pre>
</div>
<p>Ok lets see in the given below flow of the diagram.</p>
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/04/Untitled-1.jpg" border="0" /></div>
<p>In Hibernate 2 does not proxy objects by default. However, experience has shown that using object proxies is preferred, so this is the default in Hibernate 3.</p>
<div style="background-color: #f2f9fc; border: 1px solid #c9e6f2; border-radius: 3px; padding: 16px; line-height: 1.45;"><span style="color: red; font-size: x-large; text-align: center;"><b>Popular Tutorials</b></span></p>
<ul style="text-align: left;">
<li><b><a href="https://dineshonjava.com/spring-tutorial/"><em><strong>Spring Tutorial</strong> </em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-web-mvc-framework-chapter-38/"><strong><em>Spring MVC Web Tutorial </em></strong></a></b></li>
<li><b><a href="https://dineshonjava.com/introduction-to-spring-boot-a-spring-boot-complete-guide/"><strong>Spring Boot Tutorial</strong> </a></b></li>
<li><b><a href="https://dineshonjava.com/spring-security-take-baby-step-to-secure/"><em>Spring Security Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-aop-tutorial-with-example-aspect-advice-pointcut-joinpoint/"><em>Spring AOP Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/using-spring-jdbc-framework-chapter-32/"><em>Spring JDBC Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-hateoas-hypermedia-driven-restful-web-service/"><em><strong>Spring HATEOAS </strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/microservices-with-spring-boot/"><em><strong>Microservices with Spring Boot</strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/jax-rs-web-service-tutorial/"><strong><em>REST Webservice</em> </strong></a></b></li>
<li><b><a href="https://dineshonjava.com/core-java-baby-step-to-be-best-java-ian/"><em><strong>Core Java </strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/hibernate-3-on-baby-steps/"><em><strong>Hibernate Tutorial</strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-batch-process-with-example/"><strong><em>Spring Batch</em> </strong></a></b></li>
</ul>
</div>
<div style="color: #20124d;">In Hibernate 3, when we fetching the user object from the database actually its retrieved the proxy object of the user class means only first level of the fields are initializing with the associated values from the database. Field <b>listOfAddresses</b> does not have the value. If you want the list address you should call the following method you will get the <b>listOfAddresses.</b></div>
<div style="color: #20124d;">
<p><b> user.getListOfAddress(); &#8212;>;>; </b>this return the list of the address associated with that particular user which name is<b> XYZ </b>this is the default behavior of the Hibernate 3<b>. </b></p>
<div style="color: blue;">Now we look about the fetching strategies.</div>
<div style="color: blue;"><b style="color: #20124d;">Fetching Strategies:</b> there are two types of the fetching strategies in the hibernate.</div>
<div style="color: blue;">1. Lazy Fetch type</div>
<div style="color: blue;">2. Eager Fetch type</div>
<pre class="lang-java prettyprint"> LAZY = fetch when needed 
 EAGER = fetch immediately</pre>
<div style="color: blue;"></div>
<h2 style="color: blue;"><b>1. Lazy Fetch Type: </b>This the default fetch type of the hibernate 3.</h2>
<p>Now when you load a User from the database, JPA loads its id, name, and address fields for you. But you have two options for users: to load it together with the rest of the fields (i.e. eagerly) or to load it on-demand (i.e. lazily) when you call the user&#8217;s <b>getListOfAddresses()</b> method.</p>
<p>Lazy/Select Fetch strategy:- Select Fetch strategy is the lazy fetching of associations. The purpose of Lazy strategy is memory optimization . When I say memory optimization it means it means it saves us from heap error. This is what I think. So we can say yes if we are loading too objects in aseesion we should go for Lazy Fetch strategy but in terms of time performance it does not provide any Benefit. Agreed?</p>
<p>When a user has many addresses it is not efficient to load all of its addresses with it when they are not needed. So in suchlike cases, you can declare that you want addresses to be loaded when they are actually needed. This is called lazy loading.</p>
</div>
<div style="color: #20124d;"><b>EXAMPLE:</b> UserDetails.java</div>
<div style="background-color: #ff99cc; border-width: thin; border: solid;">
<p>package com.sdnext.hibernate.tutorial.dto;</p>
<p>import java.util.ArrayList;<br />
import java.util.Collection;</p>
<p>import javax.persistence.Column;<br />
import javax.persistence.ElementCollection;<br />
import javax.persistence.Entity;<br />
import javax.persistence.FetchType;<br />
import javax.persistence.GeneratedValue;<br />
import javax.persistence.GenerationType;<br />
import javax.persistence.Id;<br />
import javax.persistence.JoinColumn;<br />
import javax.persistence.JoinTable;<br />
import javax.persistence.Table;<br />
<b style="color: purple;"><br />
@Entity<br style="color: #20124d;" />@Table (name=&#8221;USER_DETAIL&#8221;)</b><br />
public class UserDetails<br />
{<br />
<b>@Id<br style="color: #20124d;" /> @Column(name=&#8221;USER_ID&#8221;)<br style="color: #20124d;" /> @GeneratedValue(strategy=GenerationType.AUTO)</b><br />
private int userId;</p>
<p><b style="color: #20124d;">@Column(name=&#8221;USER_NAME&#8221;) </b><br />
private String userName;</p>
<p><b style="color: #20124d;">@ElementCollection(fetch=FetchType.LAZY)<br />
@JoinTable(name=&#8221;USER_ADDRESS&#8221;, joinColumns=@JoinColumn(name=&#8221;USER_ID&#8221;))</b><br />
private Collection<;Address>; lisOfAddresses = new ArrayList<;Address>;();</p>
<p>public Collection<;Address>; getLisOfAddresses() {<br />
return lisOfAddresses;<br />
}<br />
public void setLisOfAddresses(Collection<;Address>; lisOfAddresses) {<br />
this.lisOfAddresses = lisOfAddresses;<br />
}<br />
public int getUserId() {<br />
return userId;<br />
}<br />
public void setUserId(int userId) {<br />
this.userId = userId;<br />
}<br />
public String getUserName() {<br />
return userName;<br />
}<br />
public void setUserName(String userName) {<br />
this.userName = userName;<br />
}<br />
public String toString()<br />
{<br />
return &#8220;[User Name: &#8220;+userName+&#8221;n Office Address: &#8220;+lisOfAddresses+&#8221;]&#8221;;<br />
}<br />
}</p>
</div>
</div>
<p> ;</p>
<div style="color: #073763;">Now <b>hibernate.cfg.xml</b> and <b>Address.java</b> are same as the previous tutorial.</div>
<div style="color: #073763;"></div>
<div style="color: #073763;">Now run the this with following class.</div>
<div style="color: #073763;"><b>HibernateTestDemo.java</b></div>
<div style="background-color: #ff99cc; border-width: thin; border: solid;">
<p>package com.sdnext.hibernate.tutorial;</p>
<p>import org.hibernate.Session;<br />
import org.hibernate.SessionFactory;<br />
import org.hibernate.cfg.AnnotationConfiguration;</p>
<p>import com.sdnext.hibernate.tutorial.dto.Address;<br />
import com.sdnext.hibernate.tutorial.dto.UserDetails;</p>
<p>public class HibernateTestDemo {<br />
/**<br />
* @param args<br />
*/<br />
public static void main(String[] args)<br />
{<br />
UserDetails user = new UserDetails(); // create user object<br />
//user.setUserId(1);<br />
user.setUserName(&#8220;Dinesh Rajput&#8221;);</p>
<p>Address address1 = new Address(); // create address object<br />
address1.setStreet(&#8220;First Street&#8221;);<br />
address1.setCity(&#8220;First City&#8221;);<br />
address1.setState(&#8220;First State&#8221;);<br />
address1.setPincode(&#8220;First Pin&#8221;);</p>
<p>Address address2 = new Address(); // create another address object<br />
address2.setStreet(&#8220;Second Street&#8221;);<br />
address2.setCity(&#8220;Second City&#8221;);<br />
address2.setState(&#8220;Second State&#8221;);<br />
address2.setPincode(&#8220;Second Pin&#8221;);</p>
<p>user.getLisOfAddresses().add(address1); // set the addresses objects to list of the addresses<br />
user.getLisOfAddresses().add(address2);</p>
<p>SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); // create session factory object<br />
Session session = sessionFactory.openSession(); // create session object<br />
session.beginTransaction(); // start transaction object<br />
session.save(user); // save the user to database<br />
session.getTransaction().commit(); // commit the transaction<br />
session.close(); // closing session</p>
<p>session = sessionFactory.openSession(); // again create another session object<br />
user = null;<br />
user = (UserDetails) session.get(UserDetails.class, 1); // retrieved the user from the database for particular user which user id = 2 this object it is proxy user object.<br />
System.out.println(user.getLisOfAddresses().size());<br />
}<br />
}<br />
******************************************************************************<br />
<b>OUTPUT:</b>Look care fully the output has the two select query one is for user and another is for address table when we call <b>getListOfAddresses()</b>; <b></b><br />
<b><br />
</b><br />
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).<br />
log4j:WARN Please initialize the log4j system properly.<br />
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)<br />
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)<br />
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)<br />
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=?<br />
Hibernate: select lisofaddre0_.USER_ID as USER1_0_, lisofaddre0_.CITY_NAME as CITY2_0_, lisofaddre0_.PIN_CODE as PIN3_0_, lisofaddre0_.STATE_NAME as STATE4_0_, lisofaddre0_.STREET_NAME as STREET5_0_ from USER_ADDRESS lisofaddre0_ where lisofaddre0_.USER_ID=?<br />
<b>2</b><br />
<b>******************************************************************************</b><br />
<b>Now if you change to some lines of code for this class file to verify the PROXY object.</b><br />
<b>Before calling getListOfAddresses() method close the session then look what happens.</b><br />
<b><br />
</b><br />
session = sessionFactory.openSession(); // again create another session object<br />
user = null;<br />
user = (UserDetails) session.get(UserDetails.class, 1); // retrieved the user from the database for particular user which user id = 2 this object it is proxy user object.<br />
session.close(); <b style="color: red;">// close the session before calling collection getter</b><br />
System.out.println(user.getLisOfAddresses().size());</p>
<p><b>Now Output: </b><br />
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).<br />
log4j:WARN Please initialize the log4j system properly.<br />
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)<br />
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)<br />
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)<br />
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=?<br />
Exception in thread &#8220;main&#8221; org.hibernate.<b>LazyInitializationException</b>: <b>failed to lazily initialize a collection of role: com.sdnext.hibernate.tutorial.dto.UserDetails.lisOfAddresses, no session or session was closed</b><br />
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException<br />
(AbstractPersistentCollection.java:380)<br />
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected<br />
(AbstractPersistentCollection.java:372)<br />
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)<br />
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248)<br />
at com.sdnext.hibernate.tutorial.HibernateTestDemo.main(HibernateTestDemo.java:48)<br />
******************************************************************************<br />
As above code failed run because when we are using the LAZY Type strategy of fetching an object hibernate session return the proxy object, it exist in the session if we are closing the session the lazy loading is not happening.</p>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/04/outputforfetching.jpg" width="640" height="81" border="0" /></div>
<div style="color: #20124d;"></div>
<div style="color: #20124d;"></div>
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/04/outputforfetching1.jpg" width="640" height="100" border="0" /></div>
<h2><b style="color: #20124d;">2. Eager Fetch Strategy:</b></h2>
<p>In hibernate 2 this is default behavior of the to retrieving an object from the database.<br />
Eager/Join Fetch strategy:- Join Fetch strategy the eager fetching of associations.The purpose of Join Fetch strategy is optimization in terms of time.I mean even associations are fetched right at the time of fetching parent object. So in this case we don’t make database call again and again . So this will be much faster.Agreed that this will bad if we are fetching too many objects in a session because we can get java heap error.</p>
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/04/eager.jpg" border="0" /></div>
<p>Now we look on the code for EAGER LOADING.</p>
<p><b>UserDetais.java</b></p>
<div style="background-color: #ff99cc; border-width: thin; border: solid;">
<p>package com.sdnext.hibernate.tutorial.dto;</p>
<p>import java.util.ArrayList;<br />
import java.util.Collection;</p>
<p>import javax.persistence.Column;<br />
import javax.persistence.ElementCollection;<br />
import javax.persistence.Entity;<br />
import javax.persistence.FetchType;<br />
import javax.persistence.GeneratedValue;<br />
import javax.persistence.GenerationType;<br />
import javax.persistence.Id;<br />
import javax.persistence.JoinColumn;<br />
import javax.persistence.JoinTable;<br />
import javax.persistence.Table;</p>
<p>@Entity<br />
@Table (name=&#8221;USER_DETAIL&#8221;)<br />
public class UserDetails<br />
{<br />
@Id<br />
@Column(name=&#8221;USER_ID&#8221;)<br />
@GeneratedValue(strategy=GenerationType.AUTO)<br />
private int userId;</p>
<p>@Column(name=&#8221;USER_NAME&#8221;)<br />
private String userName;</p>
<p><b style="color: blue;"> @ElementCollection(fetch=FetchType.EAGER)</b><br />
@JoinTable(name=&#8221;USER_ADDRESS&#8221;, joinColumns=@JoinColumn(name=&#8221;USER_ID&#8221;))<br />
private Collection<;Address>; lisOfAddresses = new ArrayList<;Address>;();</p>
<p>public Collection<;Address>; getLisOfAddresses() {<br />
return lisOfAddresses;<br />
}<br />
public void setLisOfAddresses(Collection<;Address>; lisOfAddresses) {<br />
this.lisOfAddresses = lisOfAddresses;<br />
}<br />
public int getUserId() {<br />
return userId;<br />
}<br />
public void setUserId(int userId) {<br />
this.userId = userId;<br />
}<br />
public String getUserName() {<br />
return userName;<br />
}<br />
public void setUserName(String userName) {<br />
this.userName = userName;<br />
}<br />
public String toString()<br />
{<br />
return &#8220;[User Name: &#8220;+userName+&#8221;n Office Address: &#8220;+lisOfAddresses+&#8221;]&#8221;;<br />
}<br />
}</p>
</div>
<p>Now run the following code and see the output&#8212;</p>
<div style="background-color: #ff99cc; border-width: thin; border: solid;">
<p>package com.sdnext.hibernate.tutorial;</p>
<p>import org.hibernate.Session;<br />
import org.hibernate.SessionFactory;<br />
import org.hibernate.cfg.AnnotationConfiguration;</p>
<p>import com.sdnext.hibernate.tutorial.dto.Address;<br />
import com.sdnext.hibernate.tutorial.dto.UserDetails;</p>
<p>public class HibernateTestDemo {<br />
/**<br />
* @param args<br />
*/<br />
public static void main(String[] args)<br />
{<br />
UserDetails user = new UserDetails();<br />
//user.setUserId(1);<br />
user.setUserName(&#8220;Dinesh Rajput&#8221;);</p>
<p>Address address1 = new Address();<br />
address1.setStreet(&#8220;First Street&#8221;);<br />
address1.setCity(&#8220;First City&#8221;);<br />
address1.setState(&#8220;First State&#8221;);<br />
address1.setPincode(&#8220;First Pin&#8221;);</p>
<p>Address address2 = new Address();<br />
address2.setStreet(&#8220;Second Street&#8221;);<br />
address2.setCity(&#8220;Second City&#8221;);<br />
address2.setState(&#8220;Second State&#8221;);<br />
address2.setPincode(&#8220;Second Pin&#8221;);</p>
<p>user.getLisOfAddresses().add(address1);<br />
user.getLisOfAddresses().add(address2);</p>
<p>SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();<br />
Session session = sessionFactory.openSession();<br />
session.beginTransaction();<br />
session.save(user);<br />
session.getTransaction().commit();<br />
session.close();</p>
<p>session = sessionFactory.openSession();<br />
user = null;<br />
user = (UserDetails) session.get(UserDetails.class, 1);<br />
session.close(); <b style="color: blue;">//closing the session before calling collection getter</b><br />
System.out.println(user.getLisOfAddresses().size());<br />
}<br />
}<br />
<b><br />
</b><br />
<b>OUTPUT:</b><br />
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).<br />
log4j:WARN Please initialize the log4j system properly.<br />
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)<br />
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)<br />
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)<br />
Hibernate:<b style="color: blue;"> select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_, lisofaddre1_.USER_ID as USER1_2_, lisofaddre1_.CITY_NAME as CITY2_2_, lisofaddre1_.PIN_CODE as PIN3_2_, lisofaddre1_.STATE_NAME as STATE4_2_, lisofaddre1_.STREET_NAME as STREET5_2_ from USER_DETAIL userdetail0_ left outer join USER_ADDRESS lisofaddre1_ on userdetail0_.USER_ID=lisofaddre1_.USER_ID where userdetail0_.USER_ID=?</b><br />
<b>2</b>******************************************************************************<br />
See this is successfully run the code because we are using the EAGER fetching strategy so in this strategy session return the original object with all field are initialized when load on the memory.<br />
In the above output string look care fully there are only one select statement with join clause.</p>
</div>
</div>
<p><b>So now can we say in the hibernate session where we are not loading too many objects we should go for Eager fetch as it will be much better in terms of time response(Any ways memory will be reclaimed by garbage collector once we close the session).</b></p>
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/04/eageroutput.jpg" width="640" height="67" border="0" /></div>
<p><b>In <a href="https://dineshonjava.com/hibernate-one-to-one-mapping-tutorial/">Next Chapter</a> we will discuss about <a href="https://dineshonjava.com/hibernate-one-to-one-mapping-tutorial/">One to One Mapping</a>.</b><br />
<b><br />
</b> <b> <;<;<a style="font-family: Times, 'Times New Roman', serif;" href="https://dineshonjava.com/configuring-collections-and-adding-keys/">Previous Chapter 15</a><;<; >;>;N<a style="font-family: Times, 'Times New Roman', serif;" href="https://dineshonjava.com/hibernate-one-to-one-mapping-tutorial/">ext Chapter17</a>>;>;</b></p>
<p> ;</p>
</div>

View Comments
Great Explanation. Thank you
I dont understand with the outcome of lazy loading. At the end both lazy and eager did the same. lazy fired 2 queries, Eager fired 1 query. Suppose if i want that data in the UI, which to use and can anybody pls discuss?.
Wonderful points you have mentioned here, I will be sure to
bookmark your blog and may come back in the future. thank you for sharing