我发现从Hibernate中的集合中删除时不会删除孤立记录。我必须做一些简单的错误,(这是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);
AuthorDAO代码段:
@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()
,该集合中不存在该书这种“感觉”就像我没有冲洗会话或强制更新 - 但我不知道我应该在哪里做。沿着这条路线,可能会影响的其他方面:
@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;
}
我仍然找到相同的结果。我必须遗漏一些简单的东西。
答案 0 :(得分:41)
搜索他们解决方案的人:现在在Hibernate,resp。 JPA 2.0,这是正确的方法:
@OneToMany(orphanRemoval=true)
答案 1 :(得分:19)
你没有做错任何事。你只是没有删除子实体。您可以使用子实体的显式remove()(除了您正在执行的操作)执行此操作,也可以使用导致孤立记录删除的注释。
此外,值得一提的是CascadeType.DELETE
也不会删除孤儿。这意味着别的东西。见JPA CascadeType.ALL does not delete orphans.
基本上,为了自动执行此操作,您需要在父级的集合中使用它:
org.hibernate.annotations.CascadeType.DELETE_ORPHAN
答案 2 :(得分:3)
@OneToMany
注释中的级联选项是一个数组,您想要的是:
@OneToMany(cascade={CascadeType.ALL, CascadeType.DELETE_ORPHAN})
答案 3 :(得分:0)
如果您想要“传递依赖”行为,请尝试使用以下注释。
@ org.hibernate.annotations.Cascade(CascadeType.DELETE_ORPHAN)
答案 4 :(得分:0)
请为你添加@onDelete这项工作
public class Author
{
@OneToMany(cascade={CascadeType.ALL})
@OnDelete(action = OnDeleteAction.CASCADE)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
List<Book> books;
}
答案 5 :(得分:0)
您可能会错过 mappedBy 注释。尝试:
public class Book {
@ManyToOne
@NotNull
Author author;
}
public class Author {
@OneToMany(mappedBy="author", cascade={CascadeType.ALL})
List<Book> books;
}
答案 6 :(得分:0)
我知道我参加聚会很晚,并且我知道在这个主题上已经讲了很多话,但是恕我直言,我不会使用delete-orphans作为级联选项。我宁愿在删除父级之前手动删除子级关联。一秒钟的疏忽...和一长串的关联可以在一秒钟内删除。是!我同意在某些情况下这可能恰好是我们想要的。