Thursday 26 July 2018

What is lazy loading in Hibernate? Explain with example

      In previous post, discussed the Hibernate JPA Cascade Types. In this post we can discuss the Lazy loading in Hibernate.

What is Lazy Loading in Hibernate ?


          Lazy setting decides whether to load child objects while loading the Parent Object. You need to specify parent class, Lazy = true in hibernate mapping file. Annotation based you can specify the FetchType.Lazy.
          Lazy loading means the child objects are not loaded unless they are explicitly invoked in the application by calling getChild() method on parent. In this case hibernate issues a fresh database call to load the child when getChild() is actully called on the Parent object. But in some cases you do need to load the child objects when parent is loaded. Just make the lazy=false and FetchType.EAGER(annotation based) and hibernate will load the child when parent is loaded from the database.

         The default fetch type depends on the type of the relationship. @ManyToOne and @OneToOne relationships have default FetchType.EAGER , @OneToMany and @ManyToMany relationships have default FetchType.LAZY.

Example:--

Employee.java
@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.ALL, FetchType.LAZY) 
     @JoinColumn(name="address_id")
     private Set<Address> address;
       
        // setters and getters
}

            In the above example, Employee and Address entity have the One to Many relationship. The default fetch type of One to Many relationship is LAZY.

Address.java,

@Entity
@Table (name="address")
public class Address {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="address")
     private String address;
       
        // setters and getters
}

Main Class,

HibernateMain.java,

package com.adnblog;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.adnblog.Employee;

public class HibernateMain {

      public static void main(String[] args) {

            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
            Session session = sessionFactory.openSession();
            Transaction txn = session.beginTransaction();

            Employee emp = session.get(Employee.class, 1);   //check the below output
            System.out.println("Name:--"+emp.getName());
            Set<Address> addressSet = emp.getAddress();  
            tx.commit();                     
            sessionFactory.close();
      }
}

Output :--

select  employee0_.id as id1_0_0_, employee0_.name as name1_0_0_, employee0_.address as 
address2_0_0_  from Employee employee0_ where employee0_.id=?

Name:-- Kiran

select  employee0_.id as id1_0_0_,employee0_.name as name1_0_0_, employee1_.id as id2_0_0,  employee1_.address as 
address2_0_0_  from Employee employee0_  
join Address employee1_ where employee0_.id=?
         
          In the above output, when you will call getAddress() then only will hit the address table of database and bring the address details. Initially it won't hit the Address entity, it will return proxy object.

           Hibernate does not support lazy initialization for detached objects. Access to a lazy association outside of the context of an open Hibernate session will result in an LazyInitializationException.

Summary:--


        You can use the right FetchType for your use case to avoid common Hibernate performance issues.  For most of the use cases, the FetchType.LAZY is a good choice.

        FetchType.EAGER  of  Hibernate to fetch the related entities with the initial query. This can be very efficient because all entities are fetched with only one query. But in most cases it just creates a huge overhead because you select entities you don’t need in your use case.

        FetchType.LAZY of Hibernate to delay the initialization of the relationship until you access it in your business code. The drawback of this approach is that Hibernate needs to execute an additional query to initialize each relationship.


Thank you for visiting blog.


Related Posts:--

No comments:

Post a Comment