【发布时间】:2014-07-22 02:42:27
【问题描述】:
假设我有一个实体“父”,它包含一个“子”对象列表。
在 Java 中是这样的:
public class ParentEntity implements Parent {
protected int id;
@Override
public int getId() { return id; }
@Override
public void setId(int id) { this.id = id; }
protected List<Child> children;
@Override
public List<Child> getChildren() { return children; }
@Override
public void setChildren(List<Child> children) { this.children = children; }
@Override
public void save() {
// Do some Hibernate "save" magic here...
}
public static Parent getById(int id) {
Session session = HibernateUtil.getSessionFactory().openSession();
Parent entity = (Parent) session.get(ParentEntity.class, id);
session.close();
return entity;
}
}
我的业务逻辑类只能与接口类一起使用,如下所示:
public class BusinessLogic {
public void doSomething() {
Parent parent = ParentEntity.getById(1);
for (Child c : parent.getChildren())
System.out.println("I love my daddy.");
}
}
不幸的是,这不起作用,因为父级的子级没有加载,并且循环因 NullPointerException 而崩溃。
1。方法“急切加载”
这种方法有两个问题。即使在 XML 中我写了“lazy='false'”,Hibernate 似乎也忽略了这一点。 其次,在我的情况下,急切加载是不可取的,因为我们可能有数百个孩子。
2。方法“在 'GET' 上加载/初始化”
@Override
public List<Child> getChildren()
{
if (!Hibernate.isInitialized(children)) {
Session session = HibernateUtil.getSessionFactory().openSession();
Hibernate.initialize(children);
session.close();
}
return children;
}
这也不起作用,因为我收到一个异常说该集合未链接到会话。之前用于加载父实体的会话已关闭。
您认为这里的“最佳实践”解决方案是什么?我真的不想在我的业务逻辑中弄乱 Hibernate 会话。
【问题讨论】:
-
您能解释一下为什么不能选择急切加载吗?您甚至可以为您的具体用例使用自定义查询。