2013-10-26 39 views
0

我想從我的表中刪除實體,並讓它自動刪除它的任何實體。如何自動刪除子實體?

例子:

class User { 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval=true) 
    @OnDelete(action = OnDeleteAction.CASCADE) 
    List<Address> addresses; 
} 

當我刪除沒有地址的用戶,一切工作正常。還刪除地址而不刪除用戶的作品。

但如果我嘗試刪除仍具有一些地址的用戶,我越來越org.hsqldb.HsqlException

integrity constraint violation: foreign key no action; FK_ADDRESS_USER_ID table: ADDRESS 

什麼可能是錯在這裏? 或者這是不支持的,我必須在刪除用戶之前首先明確刪除所有包含的對象Address

回答

2

我相信你有一個外鍵約束的問題。使用像Aqua Data Studio或類似的數據庫工具(您可能也可以在您的IDE中的Eclipse - Data Source Explorer視圖中執行此操作),以顯示ADDRESS表的創建腳本。它應該包含這樣的事情:

ALTER TABLE TESTSCHEMA.ADDRESS 
    ADD CONSTRAINT FK1ED033D4E91AAFD9 
    FOREIGN KEY(FK_ADDRESS_USER_ID) 
    REFERENCES TESTSCHEMA.USER(ID) 
    ON DELETE CASCADE 

問題的關鍵是你的情況ON DELETE CASCADE部分。如果缺少或不同,那可能是導致問題的原因。如果表是由Hibernate自動生成的,則此約束應該是有效的,但請記住數據庫之間存在差異。這可能是因爲在添加了Hibernate的@OnDelete註釋之前生成了表,所以現在您得到了「外鍵無操作」完整性約束違規。

與問題無關,但請注意,orphanRemoval=true將從數據庫中刪除地址,該地址從用戶實體中的集合中刪除。

此外,檢查this瞭解Hibernate支持數據庫ON DELETE CASCADE約束的細節。

+0

Hibernate是如何實現級聯的?我希望它只是在'orphanRemoval'爲true時自動刪除子實體。 – millimoose

+0

如果在映射註釋中使用'cascade'設置級聯,則可以通過Hibernate(JPA)完成,但是如果使用@OnDelete,Hibernate將在創建表時設置約束,並且級聯將在數據庫上完成級別(SQL級聯刪除),而不是常規的Hibernate機制。這具有減少Hibernate發出的SQL語句數量的功能。至於'orphanRemoval',它被用來標記實體的刪除,當它從@OneToMany集合中刪除或者一個關聯的實體從@OneToOne關聯中取消引用時,如規範中指定的那樣。 – alterfox