Hibernate在更新集合时删除孤立

Mar*_*itt 30 java hibernate orphan

我发现从Hibernate中的集合中删除时不会删除孤立记录.我必须做一些简单的错误,(这是Hibernate-101!),但我找不到它..

鉴于以下内容:

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

以下更新代码:

Author author = authorDAO.get(1);
Book book = author.getBooks().get(0);
author.getBooks().remove(0);
authorDAO.update(author);
Run Code Online (Sandbox Code Playgroud)

AuthorDAO片段:

@Override
public void update(T entity) {
    getSession().update(entity);
}
Run Code Online (Sandbox Code Playgroud)

以下测试失败:

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!
Run Code Online (Sandbox Code Playgroud)

总之,我发现:

  • 虽然书籍从作者的书籍集中删除,但它仍然存在于数据库中
  • 如果我检查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;
}
Run Code Online (Sandbox Code Playgroud)

我仍然找到相同的结果.我必须遗漏一些简单的东西.

Jak*_*kub 41

对于寻找解决方案的人:现在在Hibernate,resp.JPA 2.0,这是正确的方法:

@OneToMany(orphanRemoval=true)
Run Code Online (Sandbox Code Playgroud)


cle*_*tus 19

你没有做错任何事.你只是没有删除子实体.您可以使用子实体的显式remove()(除了您正在执行的操作)执行此操作,也可以使用导致孤立记录删除的注释.

此外,值得一提的是,CascadeType.DELETE也不会删除孤儿.这意味着别的东西.请参阅JPA CascadeType.ALL不会删除孤儿.

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

org.hibernate.annotations.CascadeType.DELETE_ORPHAN
Run Code Online (Sandbox Code Playgroud)

  • 您仍然需要自己管理Java关系.这意味着如果关系是双向的,则必须在子节点中将父节点设置为null. (6认同)
  • 你是否也将书中的作者参考设置为null? (2认同)