2008-10-13 149 views
9

我有一個實體[Project]包含其他實體集合[Questions]。休眠刪除級聯

我制訂與「​​全刪除,孤兒」級聯屬性的關係。

在我的DB的關係映射與問題表PROJECT_ID(FK)領域。此字段不能爲空,因爲我不想要沒有項目的問題。

當我使用Session.delete(項目),它拋出一個異常說PROJECT_ID不能爲null,但如果我刪除非空約束到該字段,刪除工作良好。

任何人知道如何解決這個問題?

+0

您可能應該顯示映射的相關部分。我一直使用all-delete-orphan來處理非空外鍵,並且從來沒有遇到任何問題。 – 2008-10-14 04:07:49

回答

-2

刪除發生在項目上,並且級聯到問題上,但是項目刪除在問題中包含了對project_id的空值(用於參照完整性)。在刪除Question對象時沒有得到異常,但是因爲級聯正試圖爲null FK的問題(S)。

綜觀「Java Persistence with Hibernate」,我認爲你真正想要的刪除級聯型或刪除,不刪除孤兒。

+0

這並不能解決任何問題 – 2008-10-14 00:01:31

0

一種策略是使其儘快標誌着數據庫上刪除級聯的外鍵,例如NHibernate告訴數據庫中刪除一個項目,數據庫本身會級聯刪除。然後你必須告訴NHibernate數據庫本身進行級聯刪除。從documentation

+0

是否可以用nhibernate 1.2? – 2008-10-14 00:23:35

11

直。這正好解釋了你的問題,我相信:

但是,此代碼

Parent p = (Parent) session.Load(typeof(Parent), pid); 
// Get one child out of the set 
IEnumerator childEnumerator = p.Children.GetEnumerator(); 
childEnumerator.MoveNext(); 
Child c = (Child) childEnumerator.Current; 

p.Children.Remove(c); 
c.Parent = null; 
session.Flush(); 

不會從數據庫中刪除℃;它只會刪除鏈接到p(在這種情況下會導致違反NOT NULL約束)。你需要顯式地刪除()孩子。

Parent p = (Parent) session.Load(typeof(Parent), pid); 
// Get one child out of the set 
IEnumerator childEnumerator = p.Children.GetEnumerator(); 
childEnumerator.MoveNext(); 
Child c = (Child) childEnumerator.Current; 

p.Children.Remove(c); 
session.Delete(c); 
session.Flush(); 

現在,在我們的情況下,一個孩子不能沒有父母就真的存在。所以如果我們從集合中刪除一個孩子,我們確實希望它被刪除。爲此,我們必須使用cascade =「all-delete-orphan」。

<set name="Children" inverse="true" cascade="all-delete-orphan"> 
    <key column="parent_id"/> 
    <one-to-many class="Child"/> 
</set> 

編輯:

至於逆東西,我相信這不僅決定是如何生成的SQL,看到這個doc獲取更多信息。

有一點要注意的是,你有沒有在你的Hibernate配置的多對一的關係得到了

not-null="true" 

+0

對不起。這確實有用,但我不明白爲什麼。從文檔中可以看到,當您映射雙向關聯時(這不是我的情況),會使用反向真實,反正添加它可以很好地工作。謝謝。如果你編輯解釋爲什麼inverse = true的作品,我會接受你的回答 – 2008-10-14 13:46:09