我发现从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()
这种“感觉”就像我没有刷新会话或适当地强制进行更新-但我不确定应该在哪里进行。沿着这种脉络,可能会影响其他方面:
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
任何建议将不胜感激!
编辑: 感谢所有的反馈已经。除了下面的评论,我已经将@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)父添加了,所以现在是:
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
public class Author { @OneToMany(cascade={CascadeType.ALL}) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) List<Book> books; }
我仍然找到相同的结果。我必须缺少一些简单的东西。
你没做错什么 您只是不删除子实体。您可以通过对子实体的显式remove()进行此操作(除了您正在执行的操作),也可以使用该注释使记录被删除。
另外,值得一提的是CascadeType.DELETE也不会删除orphan。那意味着其他。
CascadeType.DELETE
基本上,要自动执行此操作,您需要在父级的集合中使用它:
org.hibernate.annotations.CascadeType.DELETE_ORPHAN