範圍
對於那些沒有玩過這兩種設計的人來說,懶惰和渴望的範圍在 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 初始化集合元素