Example of FetchType.EAGER and FetchType.LAZY in Hibernate Annotation

By Arvind Rai, February 05, 2013
In Hibernate, FetchType.EAGER and FetchType.LAZY is used for collection. While mapping two entities we can define the FetchType for the mapping property. Mapping property will return collection. If we set FetchType.LAZY, then until we fetch the collection, the collection will not be loaded. If we set FetchType.EAGER, then collection will be loaded at the same time when the parent entity is loaded. FetchType is useful for the performance of system. If an entity is not needed to load collections, FetchType can be set to LAZY and vice- versa. We will run the example once by FetchType.LAZY and once by FetchType.EAGER.
Country.java
package com.concretepage.persistence;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
public class Country implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	@Column(name="id")
	private int id;
	
	@Column(name="name")
	private String name;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@JoinColumn(name="countryId") 
	private Set<State> states;
	
	public Country(int id,String name,Set<State> states){
		this.id=id;
		this.name=name;
		this.states=states;
	}
	public Country(){
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<State> getStates() {
		return states;
	}
	public void setStates(Set<State> states) {
		this.states = states;
	}
}
 
State.java
package com.concretepage.persistence;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "state")
public class State {
	@Id
	@Column(name = "id")
	private int id;

	@Column(name = "name")
	private String name;
	
	@Column(name="cid")
	private int countryId;
	public State(int id,int countryId,String name){
		this.id=id;
		this.name=name;
	}
	public State(){}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getCountryId() {
		return countryId;
	}

	public void setCountryId(int countryId) {
		this.countryId = countryId;
	}
}
 
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.url">
    jdbc:mysql://localhost:3306/hibernate</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.connection.pool_size">10</property>
    <property name="show_sql">true</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <mapping class="com.concretepage.persistence.State"/>
    <mapping class="com.concretepage.persistence.Country"/>
   </session-factory>
</hibernate-configuration>
 
HibernateUtil.java
package com.concretepage.util;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import com.concretepage.persistence.Country;
import com.concretepage.persistence.State;

public class HibernateUtil {
	private static final SessionFactory concreteSessionFactory;
	    static {
	        try {
	            concreteSessionFactory = new AnnotationConfiguration()
	                    .configure().buildSessionFactory();
	        } catch (Throwable ex) {
	            throw new ExceptionInInitializerError(ex);
	        }
	    }
	    public static Session getSession()
	            throws HibernateException {
	        return concreteSessionFactory.openSession();
	    }
	    
	    public static void main(String... args){
	    	Session session=getSession();
	    	session.beginTransaction();
	    	State s1= new State(1,1,"UP");
	    	State s2= new State(2,1,"MP");
	    	Set<State> states= new HashSet<State>();
	    	states.add(s1);
	    	states.add(s2);
	    	Country country= new Country(1,"India",states);
	    	session.persist(country);
	    	session.getTransaction().commit();
	    	session.close();
	    	//start new session to check fetch type
	        session=getSession();
	    	session.beginTransaction();
	    	Country con= (Country)session.get(Country.class,new Integer(1));
			//access collection
	    	System.out.println(con.getStates().size());
	        session.clear();
	    }
	}
 
Hibernate: insert into Country (name, id) values (?, ?)
Hibernate: insert into state (cid, name, id) values (?, ?, ?)
Hibernate: insert into state (cid, name, id) values (?, ?, ?)
Hibernate: update state set countryId=? where id=?
Hibernate: update state set countryId=? where id=?
Hibernate: select country0_.id as id1_0_, country0_.name as name1_0_ from Country country0_ where country0_.id=?
Hibernate: select states0_.countryId as countryId1_1_, states0_.id as id1_, states0_.id as id0_0_, states0_.cid as cid0_0_, states0_.name as name0_0_ from state states0_ where states0_.countryId=? 
2
 
First we have used FetchType.LAZY. Look at the above query of select. In first select query, only country has been selected and when we print the clollection size, hibernates fetches the state table data. This is LAZY fetching, means when needed only when fetch the data.

Now do changes in Country.java and make FetchType as FetchType.EAGER.
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
	@JoinColumn(name="countryId")
	private Set states;
 
See the output.
Hibernate: insert into Country (name, id) values (?, ?)
Hibernate: insert into state (cid, name, id) values (?, ?, ?)
Hibernate: insert into state (cid, name, id) values (?, ?, ?)
Hibernate: update state set countryId=? where id=?
Hibernate: update state set countryId=? where id=?
Hibernate: select country0_.id as id1_1_, country0_.name as name1_1_, states1_.countryId as countryId1_3_, states1_.id as id3_, states1_.id as id0_0_, states1_.cid as cid0_0_, states1_.name as name0_0_ from Country country0_ left outer join state states1_ on country0_.id=states1_.countryId where country0_.id=?
2
 
Look at the above select query. This time we are using FetchType.EAGER. There is only one select query in which Country and State both has been fetched. This is EAGER fetching.
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us