2011-12-08 78 views
1

使用cascade = CascadeType.REMOVE hibernate在表生成過程中不會添加'ON DELETE CASCADE'。這是正確的行爲嗎?如果我在父對象上執行em.remove()時沒有問題,但是當我嘗試通過HQL執行批量刪除時會引發錯誤。休眠不會添加'on delete cascade'

PostgreSQL 9.1,Hibernate 4.0.0.CR7

回答

7

您正在查找的是@OnDelete註釋,它影響由hibernate(DDL語句)生成模式。但是,如果批量刪除數據庫中的外鍵定義中沒有ON DELETE CASCADE子句,則此批註不會級聯刪除以引用實體/行。

@OneToMany 
@OnDelete(action=OnDeleteAction.CASCADE) 
public Set<Stuff> getStuff() { 
    return stuff; 
} 
+0

Hibernate會讓我瘋狂。 @OnDelete在@OneToMany上工作,但不在@OneToOne上!此外,它不是便攜式的。當cascade = CascadeType.REMOVE'時,其他ORM是否應用'ON DELETE CASCADE'? – Alf

+0

@tscho任何想法如何實現這一對一對一的映射? – Sikorski

+0

@Sikorski我設法使用'@ OneToOne'映射工作得很好。使用hibernate 4.2.1。 –

2

這是預期的行爲。級聯註釋告訴Hibernate將級聯級聯,這是Hibernate的職責,而不是數據庫。

批量刪除查詢完全繞過會話和實體級聯註釋。當你選擇使用它們時,你必須處理級聯刪除你自己。

1

我的理解是您所指的'ON DELETE CASCADE'功能是數據庫觸發器。 Hibernate不配置觸發器。使用註釋,Hibernate將使用標準的SELECT和DELETE語句來管理子對象的刪除。如果你打開調試程序,你會看到這種情況發生。當你第一次開始使用hibernate時,這看起來好像很低效,所以這就是你希望通過你所指的HQL來使用批量刪除。

因此,表生成不會添加觸發器等數據庫特定功能。如果您希望能夠刪除子對象嘗試這樣的事情根據您的要求

@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true) 
private List<Case> cases = new ArrayList<Case>(); 

當使用HQL其直接繞過級聯邏輯,所以您可能需要編寫自己的「清理」代碼運行定期清理orhapns等爲了提高效率,我選擇爲此編寫存儲過程。

另一種方法是檢索要刪除的父對象的集合,並逐個循環。如果你的收藏很大,這個效率不高,但至少會像你在annontation中定義的那樣級聯。