Hibernate集合保留对已删除实体的引用

时间:2017-03-08 22:13:43

标签: java hibernate orm spring-data-jpa

我们使用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

1 个答案:

答案 0 :(得分:1)

所以我在使用调试器挖掘hibernate代码之后终于解决了这个问题。分离实体的集合实际上是一个PersistentBag,这不应该太令人惊讶。 但是持久化包保持了一个snapShot,当我将集合设置为空列表时,它不会被清除。

为了测试我的最终理论,我补充了以下内容:

((PersistentCollection)e1.getE2Collection()).setSnapshot(null, null, null);

在此之后,hibernate持久化上下文能够成功合并分离的实体,并将E2集合设置为空列表。