2009-08-20 76 views
25

我發現在從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(),書不存在該集合

這「感覺」像我沒有沖洗會議或適當強制更新 - 但我不知道我應該在那裏做什麼。沿着靜脈,可能影響其他幾點:

  • 我執行上面的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; 
} 

我仍然發現了同樣的結果。我必須錯過簡單的事情。

回答

16

你沒有做錯什麼。你只是不移除子實體。你可以通過顯式remove()子實體(除了你正在做的事情)或者使用該註釋來刪除孤立記錄。

此外,值得一提的是,CascadeType.DELETE不會刪除孤兒無論是。這意味着別的東西。見JPA CascadeType.ALL does not delete orphans.

基本上做到這一點自動,你會想這對父集合:使用以下annoation

org.hibernate.annotations.CascadeType.DELETE_ORPHAN 
+0

我已經添加了這個註釋,但它仍然不工作 - 結果與以前相同。 – 2009-08-20 09:25:40

+2

您是否也將本書中的作者參考設置爲null? – cletus 2009-08-20 09:42:50

+0

不,我認爲這是DELETE_OPRHAN註釋的要點? – 2009-08-20 10:01:29

0

嘗試,如果你想「傳遞依賴」水煤漿。

@ org.hibernate.annotations.Cascade(CascadeType的。DELETE_ORPHAN)

3

@OneToMany註釋級聯選項是一個數組,你想要的是:

@OneToMany(cascade={CascadeType.ALL, CascadeType.DELETE_ORPHAN}) 
0

請加@onDelete也許這對你的工作

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

嗨。這也沒有效果。 – 2009-08-20 10:25:28

+0

你是否提交會話或刪除後清除? – Am1rr3zA 2009-08-20 12:07:04

0

看起來像你可能會缺少mappedBy註釋。嘗試:

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

尋找他們的解決方案的人:現在在Hibernate,resp。 JPA 2.0,這是正確的方法:

@OneToMany(orphanRemoval=true)