从OneToMany集合中删除时的EntityNotFoundException

时间:2014-08-13 13:02:37

标签: java hibernate jpa

我有两个实体连接了双向OneToMany / ManyToOne关系。

@Entity
class One {
  @OneToMany(mappedBy = "one", orphanRemoval = true, fetch = FetchType.EAGER)
  private Set<Many> manies;

  // ...
}

@Entity
class Many {
  @ManyToOne
  @JoinColumn(name = "one_id", nullable = false)
  private One one;

  // ...
}

如果我要删除Many个实例,请将其从One manies Set中删除,然后将其从数据库中删除。如果我采用相同的One实例并再次保存(因为我改变了任何内容,它不必与关系相关),我得到一个例外:

  

javax.persistence.EntityNotFoundException:无法找到id为12345的test.Many

ID(在此示例中为12345)是刚刚删除的实体的ID。请注意,删除实体12345成功:事务成功提交,并从数据库中删除该行。

使用Spring Data存储库添加和删除实例。删除看起来或多或少像这样:

one.getManies().remove(manyToRemove);
oneDao.save(one);
manyDao.delete(manyToRemove);

我调试了一点,发现Set是一个Hibernate PersistentSet,其中包含一个字段storedSnapshot。这又是另一个Set仍然引用被删除的实体。我不知道为什么这个引用没有从快照中删除但我怀疑这是问题:我认为Hibernate试图第二次删除该实体,因为它在快照中但不在实际集合中。我搜索了很长一段时间,但我没有遇到类似问题的其他人。

我使用Hibernate 4.2.2和Spring Data 1.6.0。

我在做一些内在错误的事情吗?我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

我遇到了同样的问题。

解决方法是替换整个集合。

Set<Many> maniesBkp = one.getManies(); // Instance of PersistentSet
maniesBkp.remove(manyToRemove);

Set<Many> manies = new HashSet<Many>();
manies.addAll(maniesBkp);

one.setManies(manies);

...
manyDao.delete(manyToRemove);
...
oneDao.save(one);

答案 1 :(得分:2)

由于您的@OneToMany关系有orphanRemoval = true,您不必从数据库中显式删除子元素 - 只需将其从集合中删除并保存父元素。

答案 2 :(得分:0)

尝试添加CascadeType.REMOVE和orphanRemoval

 @OneToMany(mappedBy = "one", orphanRemoval = true, fetch = FetchType.EAGER, cascade = CascadeType.REMOVE, orphanRemoval = true)

比执行删除

one.getManies().remove(manyToRemove);
oneDao.save(one);

编辑: 我创建了POC,查看UserRepositoryIntegrationTest.departmentTestCase(code