JPA EntitiyManager - 通过 id 查找 Parent 不具有先前添加的 children 实例 return
JPA EntitiyManager - find Parent by id does not return instance with previously added children
假设我们在 Parent 和 Child object 之间有标准的 one-to-many 关系。换句话说,一个 Parent 包含 Child object 的列表。
映射是标准的...类 中的 ID 都用 @GeneratedValue(strategy = GenerationType.IDENTITY) 注释...有所有的 getter 和 setter...
Parent{
....
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
Collection<Child> children;
....
}
Child{
...
@ManyToOne(optional = false)
Parent parent;
...
}
Child object 是关系的拥有方。当我保存拥有 Child object 并在获取 Parent object 之后,我希望之前在 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?)
...我希望已保存的 Parent 在 collection 之前保存了一个 child。但是,出于某种原因,这不起作用。有什么想法吗?
默认@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 实体已被缓存(没有 children)并保存在数据库中,这就是你得到 0 children 的原因。您需要做的就是在调用 Parent 之前清理会话。这将使用您的 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:请注意 clear 方法,如果您还没有刷新,请不要调用它。
假设我们在 Parent 和 Child object 之间有标准的 one-to-many 关系。换句话说,一个 Parent 包含 Child object 的列表。
映射是标准的...类 中的 ID 都用 @GeneratedValue(strategy = GenerationType.IDENTITY) 注释...有所有的 getter 和 setter...
Parent{
....
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
Collection<Child> children;
....
}
Child{
...
@ManyToOne(optional = false)
Parent parent;
...
}
Child object 是关系的拥有方。当我保存拥有 Child object 并在获取 Parent object 之后,我希望之前在 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?)
...我希望已保存的 Parent 在 collection 之前保存了一个 child。但是,出于某种原因,这不起作用。有什么想法吗?
默认@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 实体已被缓存(没有 children)并保存在数据库中,这就是你得到 0 children 的原因。您需要做的就是在调用 Parent 之前清理会话。这将使用您的 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:请注意 clear 方法,如果您还没有刷新,请不要调用它。