范围

对于那些没有玩过这两种设计的人来说,懒惰和渴望的范围在 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 初始化集合元素