list() iterate() Lazy Eager Initialization Hibernate

list() iterate() Hibernate

Before going into the subject, first let us know what is meant by lazy initialization and eager initialization. Concept-wise, a good programming practice is lazy initialization; but both have their own importance in coding.

Lazy initialization (or instantiation)

There are two types of initializations in a programming language – eager initialization and lazy initialization. In eager initialization, the object is created in the program execution, in a normal way, which sometimes the programmer may not use it in the program. This looks waste of memory and processor time. Other way is to create the object when the programmer really requires. This is called lazy initialization (one of the design patterns). That is, if the object is created at runtime, only when the programmer requires is known as lazy initialization. So, which is preferred, definitely you say lazy initialization. Lazy initialization is basically meant for improving the performance by avoiding unnecessary computation (load on the microprocessor) and reducing memory requirements.

Some examples:

1. Suppose you have Customer object having a big array of orders to display. To display the list to the customer it is very expensive as it requires lot of hits to database. It the Customer object is initialized at the beginning of the program which later found that Customer never asks to display his orders. Now, as you can guess, it is the time for lazy initialization.

2. Another scenario is when an object is very expensive (takes long time to create) to create, if you would like to defer (delay) its creation due to other more expensive operations takes place. Say, your program creates many object instances when it starts, but a few are required immediately. Now lazy initialization is the time to think to increase the startup performance of the program by delaying the initialization after the required and preferred objects have been created. Let us take a small code:

public class Demo
{
  private Player newPlayer = new Player();         // object is created well in advance
      
  public Player getPlayer()
  {
    return newPlayer;
  }
  public static void main(String args[])
  {
    Demo d1 = new Demo();
    Player p1 = d1.getPlayer();
  }
}

When you see this above code, after knowing what is lazy initialization, definitely you say it is meaningless, as the newPlayer object is created at the startup of the program itself which may not be required later (wasting its creation time).

The above code is modified as follows for lazy initialization.

public class Demo
{
  private Player newPlayer;
      
  public Player getPlayer()
  {
    if(newPlayer == null)
    {
      newPlayer = new Player();          // object is created when asked
    }
    return newPlayer;
  }
  public static void main(String args[])
  {
    Demo d1 = new Demo();
    Player p1 = d1.getPlayer();
  }
}

In the above code, the creation of newPlayer object is delayed making sure we do not create it until it is required.

With the above knowledge of lazy and eager initialization, let us go into our Hibernate subject.

Query methods of list() iterate() Hibernate

Fetching multiple records with Query methods: list() and iterate()

Use the same First program – Student. Change with the client program given below.

Client program: ListAndIterate.java

import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ListAndIterate 
{
  public static void main(String[] args) 
  {
    Configuration c = new Configuration();
    c.configure("/hibernate.cfg.xml");
    SessionFactory sf = c.buildSessionFactory();
    Session s = sf.openSession();
					// EAGER FETCHING WITH list()
    System.out.println("Printing with list()");
    Query q = s.createQuery("FROM Student");
    List list = q.list();
    if(list.size() != 0)
    {
      Iterator it = list.iterator();
      while(it.hasNext())  
      {
        Student std = (Student)it.next();
        System.out.println(std.getSid() + "  " + std.getSname() + "  " + std.getSmarks()+ " " + std.getSjoindate());
      }
    }
    else
    {
      System.out.println("No records exist");
    }
		                        // same above output using using JDK 1.5 style of for loop
    System.out.println("Printing with for() of JDK 1.5");
    List list1 = q.list();
	      
    for(Student std : list1)
    {
      System.out.println(std.getSid() + "  " + std.getSname() + "  " + std.getSmarks()+ " " + std.getSjoindate());
    }
					// LAZY FETCHING WITH iterate()
    System.out.println("Printing with iterate()");
    Session s1 = sf.openSession();
    Query q1 = s1.createQuery("FROM Student");
    Iterator it = q1.iterate();
    if(!it.hasNext())
    {
      System.out.println("No data available");
    }
    else
    {
      while(it.hasNext())
      {
        Student std = (Student)it.next();
        System.out.println(std.getSid() + "  " + std.getSname() + "  " + std.getSmarks()+ " " + std.getSjoindate());
      }
    }
  }
}

With list() database is hit only once. With iterate(), for each iteration (record), database is hit and select query is written. You can see this in Console output (next screen).

When to use list() iterate() Hibernate?

Generally, we get the best performance with list() as for all the records only one database hit is made. Occasionally, we can prefer iterate() for better results only when all the records (required by the Query) are already available in the secondary-level (of SessionFactory) cache (if retrieved earlier). If not cached, iterate() will be very slower as for every record, it hits the database.

Console screenshot after executing the client program

image

Observe with "Printing with iterate()", iterate() method hits (accesses) the database three times to fetch three records. Other case "Printing with list()", it is, only once.

Difference between list() and iterate() methods of Query interface? or list() vs iterate()?

Both methods list() and iterate() are used to retrieve multiple records from the database table. First let us observe their signatures as defined in Hibernate API.

a) List list() throws HibernateException

Return the query results as a List. If the query contains multiple fields per row, the results are returned in an instance of Object[].

b) Iterator iterate() throws HibernateException

Return the query results as an Iterator. Entities (records) returned are initialized on demand.

Snippet of code for both methods:

For list():

Query q = s.createQuery("FROM Student");
List list = q.list();
Iterator it = list.iterator();
while(it.hasNext())  
{
  Student std = (Student)it.next();
  System.out.println(std.getSid() + "  " + std.getSname() + "  " +    std.getSmarks()+ " " + 
  std.getSjoindate());
}

For iterate():

Query q = s.createQuery("FROM Student");
Iterator it = q.iterate();
while(it.hasNext())  
{
  Student std = (Student)it.next();
  System.out.println(std.getSid() + "  " + std.getSname() + "  " + std.getSmarks()+ " " + std.getSjoindate());
}

As it can be observed, the iterate() method avoids a List object.

list() is faster as only one database hit is made.

iterate() makes lot of database hits (one hit for each record or iteration) and there by slower than list() (number of hits you can observe in the output). If the class instances are already available in the session or in second-level cache (perhaps, if iterate() will be faster (else slower) than list().

1 thought on “list() iterate() Lazy Eager Initialization Hibernate”

Leave a Comment

Your email address will not be published.