我有一个具有当前设置的父类和子类
@Entity
public class Parent {
@OneToMany(mappedBy = "parent")
private Set<Child> children;
@Column
private int type;
}
@Entity
public class Child {
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
对于某些函数,我希望在根据其类型查询父级时,自动检索子级并将其填充到集合中。
这是我迄今为止尝试过的
res = getSession().createCriteria(
Parent.class, "parent"
).createAlias(
"parent.children", "children"
).add(
Restrictions.eq("parent.type", type)
).setFetchMode(
"children", FetchMode.JOIN // FetchMode.SELECT
).list();
当我运行单元测试时,getter 始终等于 Null(我在数据库中有数据和关系)
Parent parent = new Parent();
parent.setType(ParentType.WEEK);
parentDao.save(parent);
Child child = new Child();
child.setParent(parent);
childDao.save(child);
List<Parent> res = parentDao.findByType(0, 10, ParentType.WEEK, true);
assertNotNull(res.get(0).getChildren());
assertEquals(1, res.get(0).getChildren().size());
我该如何解决这个问题?
最佳答案
您正在创建一个父级,并保留一个空子级列表。 Parent实例因此被存储在一级缓存中。
然后您将创建一个子项并保留它。
然后,您将执行一个查询来检索刚刚创建的父级。因此,Hibernate 从数据库获取 ID,发现该 ID 是已存在于缓存中的 Parent 实体之一,因此返回该 Parent 实例。由于您尚未设置其子列表,因此它仍然为空。
您有责任维护内存中实体图的一致性。 Hibernate 只关心关联的拥有方。通过设置 child 的 parent ,但不将 child 添加到 parent 的 child 中,您在实体图中引入了不连贯性。数据库中的一切都会很好,因为关联的拥有方已正确初始化。
如果您启动新事务并执行查询,子列表将被正确填充。同样,如果您在执行查询之前清除 session 。但在同一个事务中,当您初始化关联的一侧时,Hibernate 不会自动初始化另一侧。
关于java - 根据 Criteria 设置懒惰的 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23967588/