关于Hibernate延迟加载

package com.lottery.test;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "T_PERSON", schema = "XJ")
public class TPerson implements java.io.Serializable {

	private Integer id;
	private TB TB;
	private TA TA;
	private String name;
	private String age;

	public TPerson() {
	}

	@Id
	@GeneratedValue
	@Column(name = "ID", unique = true, nullable = false, precision = 20, scale = 0)
	public Integer getId() {
		return this.id;
	}

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

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "B_ID", nullable = false)
	public TB getTB() {
		return this.TB;
	}

	public void setTB(TB TB) {
		this.TB = TB;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "A_ID", nullable = false)
	public TA getTA() {
		return this.TA;
	}

	public void setTA(TA TA) {
		this.TA = TA;
	}

	@Column(name = "NAME", length = 20)
	public String getName() {
		return this.name;
	}

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

	@Column(name = "AGE", length = 20)
	public String getAge() {
		return this.age;
	}

	public void setAge(String age) {
		this.age = age;
	}

}

 

先看上面这个实体类,有两个子类TA和TB,分别使用了延迟加载

 

下面是测试方法

                Session session = HibernateSessionFactory.getSession();
		
		TPerson p =(TPerson) session.get(TPerson.class, 1);
		TPerson p1 =(TPerson) session.load(TPerson.class, 1);
		
		//session.close();
		TA a = p.getTA();
		a.getName();
		TB b = p.getTB();
		b.getName();
		System.out.println(p);
		
		session.get(TPerson.class, 1);
		session.close();
 

先谈get方法,get首先会直接去session缓存去查,没有去二级缓存查,再没有就去数据库查,如果去数据库去查会判断实体中关联的关联实体,如果关联实体使用延迟加载,则不会查询关联实体,只有在使用的时候再去查,且查询关联是使用load方式,如p.getTA()不会查询,a.getName()才会真正去查

get方式及时查,没有返回null

 

load方式,和get一样先从session缓存查,没有就去二级缓存查,在没有就生成一个代理对象,只有当使用的时候去查

load延迟查,没有抛出ObjectNotFoundException异常

 

使用延迟必须要注意,因为是延迟查询,所以如果在session关闭后在延迟查询将会抛出session关闭异常

考虑这样一种情况,session管理在Domain层,Domain查询后返回给视图层,在视图层中session是关闭的,如果再使用实体,将会异常,所以使用延迟加载必须考虑这一点

 

我一直觉得load延迟加载是否有存在的必要,laod的优势是延迟方式来提供性能,问题是难道使用者使用load获取一个实体对象会不使用它???如果会使用,则必须要查,那么延迟又有什么意义呢?

 

你可能感兴趣的:(Hibernate)