一尘不染

更新集合时hibernate删除orphan

hibernate

我发现从Hibernate的集合中删除orphan记录并没有被删除。我一定在做一些简单的错误(这是Hibernate-101!),但是我找不到它。

给定以下内容:

public class Book {
    @ManyToOne
    @NotNull
    Author author;
}
public class Author
{
    @OneToMany(cascade={CascadeType.ALL})
    List<Book> books;
}

以及以下更新代码:

Author author = authorDAO.get(1);
Book book = author.getBooks().get(0);
author.getBooks().remove(0);
authorDAO.update(author);

DAO片段:

@Override
public void update(T entity) {
    getSession().update(entity);
}

以下测试失败:

Author author = author.get(1);
assertEquals(0,author.getBooks().size()); // Passes
Book dbBook = bookDAO.get(book.getId())
assertNull(dbBook); // Fail!  dbBook still exists!
assertFalse(author.getBooks().contains(dbBook) // Passes!

总而言之,我发现:

  • 从作者的藏书中删除该书后,该书仍存在于数据库中
  • 如果我检查book.getAuthor().getBooks(),那本书不存在该书

这种“感觉”就像我没有刷新会话或适当地强制进行更新-但我不确定应该在哪里进行。沿着这种脉络,可能会影响其他方面:

  • 我正在用装饰的JUnit测试中执行以上操作 @RunWith(SpringJUnit4ClassRunner.class)
  • 我最初是在用修饰的更新例程中遇到此问题的@Transactional,但是,此后我在一个普通的旧JUnit测试中重新创建了它。

任何建议将不胜感激!

编辑:
感谢所有的反馈已经。除了下面的评论,我已经将@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)父添加了,所以现在是:

public class Author
{
    @OneToMany(cascade={CascadeType.ALL})
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    List<Book> books;
}

我仍然找到相同的结果。我必须缺少一些简单的东西。


阅读 281

收藏
2020-06-20

共1个答案

一尘不染

你没做错什么 您只是不删除子实体。您可以通过对子实体的显式remove()进行此操作(除了您正在执行的操作),也可以使用该注释使记录被删除。

另外,值得一提的是CascadeType.DELETE也不会删除orphan。那意味着其他。

基本上,要自动执行此操作,您需要在父级的集合中使用它:

org.hibernate.annotations.CascadeType.DELETE_ORPHAN
2020-06-20