如何在会话关闭后使用hibernate访问延迟加载的字段?

Pau*_*son 8 java hibernate lazy-loading

考虑这种情况:

  • 我通过hibernate加载了一个Parent实体
  • Parent包含一个大型且延迟加载的Children集合
  • 在用户查看父数据时,在初始加载后关闭hibernate会话
  • 用户可以选择查看懒惰儿童集合的内容
  • 我现在希望加载该集合

加载此系列的方法/最佳方式是什么?

  • 假设session-in-view不是一个选项,因为只有在用户查看Parent并决定查看Children之后才会获取Children集合.
  • 这是一项服务,将由基于Web和桌面的客户端远程访问.

谢谢.

Pau*_*son 7

可以使用Hibernate.initialize(parent.getCollection())加载延迟集合,但父对象需要附加到活动会话.

此解决方案获取父实体和延迟加载字段的名称,并返回完全加载集合的实体.

不幸的是,由于父需要重新连接到新打开的会话,我不能使用对延迟集合的引用,因为这将引用实体的分离版本; 因此fieldName和反射.出于同样的原因,这必须返回附加的父实体.

因此,在OP场景中,当用户选择查看延迟集合时,可以进行此调用:

Parent parentWithChildren = dao.initialize(parent,"lazyCollectionName");
Run Code Online (Sandbox Code Playgroud)

方法:

public Entity initialize(Entity detachedParent,String fieldName) {
    // ...open a hibernate session...
    // reattaches parent to session
    Entity reattachedParent = (Entity) session.merge(detachedParent); 

    // get the field from the entity and initialize it
    Field fieldToInitialize = detachedParent.getClass().getDeclaredField(fieldName);
    fieldToInitialize.setAccessible(true);
    Object objectToInitialize = fieldToInitialize.get(reattachedParent);

    Hibernate.initialize(objectToInitialize);
    return reattachedParent;
}
Run Code Online (Sandbox Code Playgroud)


zmf*_*zmf 3

我正在对用户正在查看的内容做出一些假设,但似乎您只想在用户已经查看过父级并且确实想查看子级时检索子级。

为什么不尝试打开一个新会话并由父母获取孩子呢?类似的东西......

criteria = session.createCriteria(Child.class);
criteria.add(Restrictions.eq("parent", parent));
List<Child> children = criteria.list();
Run Code Online (Sandbox Code Playgroud)