我们使用spring-data hibernate作为我们的数据库访问的ORM。我的实体设置如下:
class E1 {
@Column(name = "e1_id")
private BigDecimal e1_id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "e1", orphanRemoval=true, fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
private Collection<E2> e2List;
}
class E2 {
@Column(name = "e2_id")
private BigDecimal e2_id;
@JoinColumn(name = "e1_id", referencedColumnName = "e1_id")
@ManyToOne
private E1 e1;
}
现在我尝试以下方法: 使用spring JPA存储库创建一个新的E1并保存,而不使用显式的spring事务。
E1 detachedE1 = e1Repo.save(e1);
e1有一个非空的e2集合。
我从e1中删除e2实体,然后在弹出事务中保存e1。
然后,我尝试使用detachedE1,如下所示:
detachedE1.setE2Collection(Collections.emptyList())
e1Repo.save(detachedE1)
上面的代码出错了,错误基本上说是:
springframework.orm.jpa.JpaObjectRetrievalFailureException:无法找到id为1.00的entity.E2
我的问题是,JPA如何保留对已删除集合的引用。我将E2集合设置为空列表。我还验证了e1Repo.find(detachedE1.e1_id)返回的实体有一个空集合。
提前感谢任何回复/指针!
只是想添加我们使用hibernate hibernate-entitymanager-4.3.8.Final.jar
答案 0 :(得分:1)
所以我在使用调试器挖掘hibernate代码之后终于解决了这个问题。分离实体的集合实际上是一个PersistentBag,这不应该太令人惊讶。 但是持久化包保持了一个snapShot,当我将集合设置为空列表时,它不会被清除。
为了测试我的最终理论,我补充了以下内容:
((PersistentCollection)e1.getE2Collection()).setSnapshot(null, null, null);
在此之后,hibernate持久化上下文能够成功合并分离的实体,并将E2集合设置为空列表。