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 方法,如果您还没有刷新,请不要调用它。