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获取一个实体对象会不使用它???如果会使用,则必须要查,那么延迟又有什么意义呢?