範圍

對於那些沒有玩過這兩種設計的人來說,懶惰和渴望的範圍在 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。 ** ** **

解決方案是使用:

  1. 在檢視中開啟會話 - 即使在渲染檢視上也可以使會話保持開啟狀態。
  2. 在關閉會話之前 Hibernate.initialize(user.getLikedPage()) - 這告訴 hibernate 初始化集合元素