Hibernate: Understanding of Hibernate Fetch Strategies

Abstract

As we known, there are 3 kinds of fetch strategy in Hibernate. They are “join”,”select” and “subselect”.

In this article, I took an example with Customer and Order Entities to show you what is the different between these fetch strategies.

Hope it will useful for you. BTW, this is not a final version. I will follow up it in future.

package net.sampledb.model;

import java.util.HashSet;
import java.util.Set;

/**
 * Customers entity.
 * 
 * @author Xianyi.Ye
 */

public class Customer implements java.io.Serializable {

	// Fields

	private Long id;
	private Integer version;
	private String name;
	private String password;
	private String email;
	private Set orders = new HashSet(0);

	// Constructors

	/** default constructor */
	public Customer() {
	}

	/** minimal constructor */
	public Customer(Integer version, String name) {
		this.version = version;
		this.name = name;
	}

	/** full constructor */
	public Customer(Integer version, String name, String password,
			String email, Set orders) {
		this.version = version;
		this.name = name;
		this.password = password;
		this.email = email;
		this.orders = orders;
	}

	// Property accessors

	public Long getId() {
		return this.id;
	}

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

	public Integer getVersion() {
		return this.version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return this.email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Set getOrders() {
		return orders;
	}

	public void setOrders(Set orders) {
		this.orders = orders;
	}

}

package net.sampledb.model;

import java.util.HashSet;
import java.util.Set;

/**
 * Orders entity.
 * 
 * @author Xianyi.Ye
 */

public class SampleOrder implements java.io.Serializable {

	// Fields

	private Long id;
	private Customer customers;
	private Integer version;
	private String orderNumber;
	private Set lineitemses = new HashSet(0);

	// Constructors

	/** default constructor */
	public SampleOrder() {
	}

	/** minimal constructor */
	public SampleOrder(Integer version, String orderNumber) {
		this.version = version;
		this.orderNumber = orderNumber;
	}

	/** full constructor */
	public SampleOrder(Customer customers, Integer version, String orderNumber,
			Set lineitemses) {
		this.customers = customers;
		this.version = version;
		this.orderNumber = orderNumber;
		this.lineitemses = lineitemses;
	}

	// Property accessors

	public Long getId() {
		return this.id;
	}

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

	public Customer getCustomers() {
		return this.customers;
	}

	public void setCustomers(Customer customers) {
		this.customers = customers;
	}

	public Integer getVersion() {
		return this.version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public String getOrderNumber() {
		return this.orderNumber;
	}

	public void setOrderNumber(String orderNumber) {
		this.orderNumber = orderNumber;
	}

	public Set getLineitemses() {
		return this.lineitemses;
	}

	public void setLineitemses(Set lineitemses) {
		this.lineitemses = lineitemses;
	}

}

  
  


  
  
    
   
   
        
    
    
            
     
     
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
                
      
      
            
     
     
            
     
     
        
    
    
    
   
   

  
  

  
  


  
  
    
   
   
        
    
    
            
     
     
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
        
    
    
        
    
    
            
     
     
                
      
      
            
     
     
            
     
     
        
    
    
    
   
   

  
  

 

Fetch=”join”

  
  

  
  
    
   
   
        
    
    
    
   
   
    
   
   

  
  

Java DAO:

public List findAll() {
		log.debug("finding all Customers instances");
		try {
			String queryString = "from Customer cus";
			Query queryObject = getSession().createQuery(queryString);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

 

Java Client:

CustomersDAO dao = new CustomersDAO() ;
List list = dao.findAll() ;
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Customer customer = (Customer) iterator.next();
			customer.getOrders().size() ;
		}

 

SQL Output:

Hibernate: 
    select
        customer0_.ID as ID0_,
        customer0_.VERSION as VERSION0_,
        customer0_.NAME as NAME0_,
        customer0_.PASSWORD as PASSWORD0_,
        customer0_.EMAIL as EMAIL0_ 
    from
        sampledb.dbo.CUSTOMERS customer0_

Hibernate 1: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=?

Hibernate 2: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=?

Hibernate 3: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=?

 

If we use fetch=’join strategy to retrieve all the customers with their order objects, you will see the different from fetch=”select”.

  
  
    
   
   
        
    
    
    
   
   
    
   
   

  
  

 

Java DAO:

public List findAllWithOrders() {
		log.debug("finding all Customers instances with Orders");
		try {
			String queryString = "from Customer cus left join cus.orders";
			Query queryObject = getSession().createQuery(queryString);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

 

Java Client:

CustomersDAO dao = new CustomersDAO() ;
List list = dao.findAllWithOrders() ;

SQL Output:

Hibernate: 
    select
        customer0_.ID as ID0_0_,
        orders1_.ID as ID5_1_,
        customer0_.VERSION as VERSION0_0_,
        customer0_.NAME as NAME0_0_,
        customer0_.PASSWORD as PASSWORD0_0_,
        customer0_.EMAIL as EMAIL0_0_,
        orders1_.CUSTOMER_ID as CUSTOMER2_5_1_,
        orders1_.VERSION as VERSION5_1_,
        orders1_.ORDER_NUMBER as ORDER4_5_1_ 
    from
        sampledb.dbo.CUSTOMERS customer0_ 
    left outer join
        sampledb.dbo.SAMPLEORDERS orders1_ 
            on customer0_.ID=orders1_.CUSTOMER_ID

 

Summary of Join and Non-join:

1. The attribute “fetch” mapping will be ignored when we use HQL.

2. If we adopt “select” or other non-join fetch strategies, the associated objects will be retrieved in separately. (For our example, it will be separated to 3 independent query SQLs.)

If we adopt “join” fetch strategy, the associated objects will be retrieved with left join query. (For our example, all the associated order objects will be retrieved in a same query SQL with Left Join.)

Fetch=”select”

  
  
    
   
   
        
    
    
    
   
   
    
   
   

  
  

 

Java DAO:

public List findAll() 
{
		log.debug("finding all Customers instances");
		try {
			String queryString = "from Customer cus where cus.id in (1,2,3)";
			Query queryObject = getSession().createQuery(queryString);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
}
	}

 

Java Client:

List list = dao.findAll() ;
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Customer customer = (Customer) iterator.next();
			customer.getOrders().size() ;
		}

SQL Output:

Hibernate: 
    select
        customer0_.ID as ID0_,
        customer0_.VERSION as VERSION0_,
        customer0_.NAME as NAME0_,
        customer0_.PASSWORD as PASSWORD0_,
        customer0_.EMAIL as EMAIL0_ 
    from
        sampledb.dbo.CUSTOMERS customer0_ 
    where
        customer0_.ID in (
            1 , 2 , 3
        )

Hibernate 1: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=?

Hibernate 2: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=?

Hibernate 3: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=?

 

Fetch=”subselect”

  
  
    
   
   
        
    
    
    
   
   
    
   
   

  
  

Java DAO:

public List findAll() 
{
		log.debug("finding all Customers instances");
		try {
			String queryString = "from Customer cus where cus.id in (1,2,3)";
			Query queryObject = getSession().createQuery(queryString);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
}
	}

Java Client:

List list = dao.findAll() ;
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Customer customer = (Customer) iterator.next();
			customer.getOrders().size() ;
		}

SQL Output:

Hibernate: 
    select
        customer0_.ID as ID0_,
        customer0_.VERSION as VERSION0_,
        customer0_.NAME as NAME0_,
        customer0_.PASSWORD as PASSWORD0_,
        customer0_.EMAIL as EMAIL0_ 
    from
        sampledb.dbo.CUSTOMERS customer0_ 
    where
        customer0_.ID in (
            1 , 2 , 3
        )

Hibernate 1: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER2_1_,
        orders0_.ID as ID1_,
        orders0_.ID as ID5_0_,
        orders0_.CUSTOMER_ID as CUSTOMER2_5_0_,
        orders0_.VERSION as VERSION5_0_,
        orders0_.ORDER_NUMBER as ORDER4_5_0_ 
    from
        sampledb.dbo.SAMPLEORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID in (
            select
                customer0_.ID 
            from
                sampledb.dbo.CUSTOMERS customer0_ 
            where
                customer0_.ID in (
                    1 , 2 , 3
                )
        )

 

Summary of Select and Subselect:

1. If we use “Select” fetch strategy, each of associated objects query operation will be performed in separately.

2. If we use “Subselect” fetch strategy, all the associated objects query operation will be executed in single query statement. (For our example, Hibernate uses embed-query to optimize the query operation)

To be continue,

Xianyi.Ye

yexianyi@hotmail.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yexianyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值