假设我们在Parent和Child对象之间具有标准的一对多关系。换句话说,一个Parent包含Child对象的列表。
映射是标准的......两个类中的ID都使用@GeneratedValue注释(策略= GenerationType.IDENTITY)......有所有的getter和setter ......
Parent{
....
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
Collection<Child> children;
....
}
Child{
...
@ManyToOne(optional = false)
Parent parent;
...
}
子对象是关系的拥有方。当我保存拥有的Child对象时,在获取Parent对象之后,我希望在父对象中获得以前保存的Child。更准确地说,当我执行此代码时:
EntityManager em...
Parent p = new Parent();
em.persist(p);
em.flush();
Child c = new Child();
c.setParent(p);
em.persist(c);
em.flush();
Parent savedParent = em.find(Parent.class, p.getId());
savedParent.getChildren().size(); //this call returns 0 instead of 1 (why?)
...我希望savedParent已经在集合中保存了一个孩子。但是,由于某种原因,这不起作用。有什么想法吗?
答案 0 :(得分:1)
默认情况下,@ OneToMany设置了fetch = FetchType.LAZY,将其设置为FetchType.EAGER。
@OneToMany(fetch = FetchType.EAGER)
更新
savedParent.getChildren().size(); //this call returns 0 instead of 1 (why?)
使用 em.find(Parent.class,p.getId()); ,您将从第一级缓存中获取实体。 Parent实体已被缓存(没有子代)并保存在数据库中,这就是为什么你得到0个孩子。您需要做的就是在调用Parent之前清理会话。这将使用您的父级调用数据库,然后 savedParent.getChildren()。size()必须有效。
EntityManager em...
Parent p = new Parent();
em.persist(p);
em.flush();
Child c = new Child();
c.setParent(p);
em.persist(c);
em.flush();
em.clear(); //this will clear first level cache
Parent savedParent = em.find(Parent.class, p.getId()); // a sql is peformed
savedParent.getChildren().size(); //a sql is peformed for children.
PD:请注意清除方法,如果你没有刷新但不要打电话。