范围
对于那些没有玩过这两种设计的人来说,懒惰和渴望的范围在 SessionFactory 的特定 Session 中。 Eager 立即加载所有内容,意味着无需调用任何内容来获取它。但是懒惰的提取通常需要一些操作来检索映射的集合/对象。这有时会在会话之外进行延迟抓取。例如,你有一个显示某些映射 POJO 的详细信息的视图。 ** ** **
@Entity
public class User {
private int userId;
private String username;
@OneToMany
private Set<Page> likedPage;
// getters and setters here
}
@Entity
public class Page{
private int pageId;
private String pageURL;
// getters and setters here
}
public class LazzyTest{
public static void main(String...s){
SessionFactory sessionFactory = new SessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User user = session.get(User.class, 1);
transaction.commit();
session.close();
// here comes the lazy fetch issue
user.getLikedPage();
}
}
当你尝试在会话外获取延迟时,你将获得 lazyinitializeException 。这是因为默认情况下,所有 oneToMany 或任何其他关系的提取策略都是惰性的 (按需调用 DB),当你关闭会话时,你无权与数据库通信。所以我们的代码尝试获取 preferPage 的集合,并抛出异常,因为没有关联的会话用于渲染 DB。 ** ** **
解决方案是使用:
- 在视图中打开会话 - 即使在渲染视图上也可以使会话保持打开状态。
- 在关闭会话之前
Hibernate.initialize(user.getLikedPage())
- 这告诉 hibernate 初始化集合元素