考虑这种情况:
加载此系列的方式/最佳方式是什么?
感谢。
答案 0 :(得分:7)
可以使用Hibernate.initialize(parent.getCollection())加载延迟集合,但父对象需要附加到活动会话。
此解决方案获取父实体和延迟加载字段的名称,并返回完全加载集合的实体。
不幸的是,由于父级需要重新连接到新打开的会话,因此我不能使用对延迟集合的引用,因为这将引用实体的分离版本;因此fieldName和反射。出于同样的原因,这必须返回附加的父实体。
因此,在OP场景中,当用户选择查看延迟集合时,可以进行此调用:
Parent parentWithChildren = dao.initialize(parent,"lazyCollectionName");
方法:
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;
}
答案 1 :(得分:3)
我正在对用户正在查看的内容做出一些假设,但是如果用户已经查看了父级并且真的想要看到孩子,那么您似乎只想检索孩子。
为什么不尝试打开新会话并通过其父级获取子级?有些东西......
criteria = session.createCriteria(Child.class);
criteria.add(Restrictions.eq("parent", parent));
List<Child> children = criteria.list();
答案 2 :(得分:0)
Hibernate以与普通字段不同的方式处理集合。
在我的工作中,我们通过在个案基础上初始化我们需要的初始负载中的字段来解决这个问题。例如,在您可能拥有的事务所包围的Facade load方法中:
public Parent loadParentWithIntent1(Long parentId)
{
Parent parent = loadParentFromDAO();
for (Child c : parent.getChildren())
{
c.getField1();
}
}
我们对每个意图都有不同的外观调用。这基本上可以实现您所需要的,因为您在任何方式需要时都会加载这些特定字段,这只是在加载时将它们放入会话中。