Eager and Lazy Fetch Types in Hibernate

Consider a user class with an embedded list of addresses, or a company class with a list of employee details. By default, when you load the embedding class (user or company) using session.get, the embedded collection (addresses or employee details) is not actually retrieved from database, but only the top level fields are retrieved. The collection list is retrieved when you call the getter for that embedded collection. This is called lazy initialization fetch in hibernate. The alternative is called eager initialization fetch. In eager initialization, the embedded collections are retrieved upfront.  

We can tell hibernate whether to use lazy or eager initialization using the fetch parameter of @ElementCollection. Two possible values for the fetch parameter are FetchType.LAZY and FetchType.EAGER (e.g. @ElementCollection (fetch=FetchType.EAGER)). If you don’t specify the fetch parameter, the default is FetchType.LAZY. We will see a simple example to illustrate this. We will have a User class that refer to an Address class, and a test class. If you are not following the tutorials in order, refer to the article http://javajee.com/your-first-hibernate-program for the basic setup including hibernate configuration file and refer to http://javajee.com/embedding-value-types-within-an-entity-class-in-hibernate for the Address class.

 

Case 1: Initially the user class will use an empty @ElementCollection annotation to refer to the embedded collection. In the test class, after retrieving user, we will close session and then try to print the values of the embedded collection. The User class will look as:

package com.javajee.hiberex.dto;

 

import java.util.ArrayList;

import java.util.Collection;

import javax.persistence.ElementCollection;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.Id;

 

@Entity

public class User {

 

  @Id

  int id;

  private String name;

  @ElementCollection

  private Collection<Address> addresses = new ArrayList<Address>();

  //Getters and setters not shown, you can refer to other tutorials or generate it in eclipse.

}

 

The test class will look as below:

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

import com.javajee.hiberex.dto.Address;

import com.javajee.hiberex.dto.User;

 

public class UserTest {

 

  public static void main(String[] args) {

 

    User u = new User();

 

    u.setId(1);

    u.setName("Heartin");

    Address addr = new Address();

    addr.setHouseno(777);

    addr.setStreet("MyStreet");

    u.getAddresses().add(addr);

    u.getAddresses().add(addr);

    Configuration configuration = new Configuration();

    configuration.configure();

    ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()

        .applySettings(configuration.getProperties()).buildServiceRegistry();

    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

    Session session = sessionFactory.openSession();

    session.beginTransaction();

    session.save(u);

    session.getTransaction().commit();

 

    u = null;

    session = sessionFactory.openSession();

    session.beginTransaction();

    u = (User) session.get(User.class, 1);

    session.getTransaction().commit();

    session.close();

    for(Address add : u.getAddresses()){

      System.out.println(add.getHouseno());

    }

  }

}

 

If you execute this code, you will get this exception:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection…

This is because when you call session.get for user, only user fields (except the address list collection) is retrieved. We are then trying to print the address details after session.close, but after session.close there is no session available to retrieve the address details lazily and hence it throws an exception. If you change the @ElementCollection annotation to @ElementCollection (fetch=FetchType.LAZY), the behavior will be same and you will still get org.hibernate.LazyInitializationException. This is because FetchType.LAZY is the default.

 

Case 2: Now change the @ElementCollection annotation to @ElementCollection (fetch=FetchType.EAGER) in User class as:

@ElementCollection (fetch=FetchType.EAGER)

private Collection<Address> addresses = new ArrayList<Address>();

Execute the same TestUser class and you will get a successful response this time. This is because in EAGER initialization, you retrieve the collection during session.get for user and not retrieved after session.close.

 

Tags: 

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)