我有一个Parent类和一个带有当前设置的Child类
@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());
我该如何解决这个问题?
答案 0 :(得分:1)
您正在创建父级,将使用空子级列表,并将其保留。因此,Parent实例存储在第一级缓存中。
然后你要创造一个孩子并坚持下去。
然后,您正在执行检索刚刚创建的父级的查询。因此,Hibernate从数据库中获取ID,发现该ID是已经在缓存中的Parent实体之一,因此返回该Parent实例。由于你还没有设置它的子列表,它仍然是空的。
您有责任保持实体图在内存中的一致性。 Hibernate只关心关联的拥有方。通过设置子项的父项,但不将子项添加到父项的子项中,您在实体图中引入了不连贯性。数据库中的一切都会很好,因为关联的拥有方是正确初始化的。
如果您启动新事务并执行查询,则会正确填充子列表。同样,如果在执行查询之前清除会话。但是在同一个事务中,Hibernate在初始化另一个时不会自动初始化关联的一面。