2012-05-22 75 views
1

我在WebLogic 10.0.x上使用OpenJPA(JPA 1.0)和Oracle。我已經定義了OneToMany關係如下:OpenJPA CascadeType.DELETE導致外鍵違規

@Entity 
public class Compound implements Serializable { 
    ... 
    @OneToMany(mappedBy="compound", fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    private List<Submission> submissions = new ArrayList<Submission>(); 
    ... 
} 

@Entity 
public class Submission implements Serializable { 
    ... 
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.REFRESH) 
    @JoinColumn(name="compoundId") 
    private Compound compound; 
    ... 
} 

當我刪除一個化合物實體時,所有的子提交實體也應該被刪除。這個工程作爲一般規則,但我對這些表的外鍵約束設置:

ALTER TABLE SUBMISSION 
ADD CONSTRAINT FK_SUBMISSION_COMPOUND 
    FOREIGN KEY (COMPOUNDID) 
    REFERENCES COMPOUND(COMPOUNDID); 

現在,當我試圖刪除我遇到以下異常複合實體:

ORA-02292: integrity constraint (HELC.FK_SUBMISSION_COMPOUND) violated - child record found {prepstmnt 3740 DELETE FROM Compound WHERE compoundId = ? [params=(long) 10384]} [code=2292, state=23000]" 

的上面的異常意味着Open JPA試圖在將刪除級聯到子實體之前刪除父級。我已經閱讀了幾篇關於這個例外的文章,可以追溯到2006年。然而,最近的文章表明這​​個bug已經修復了嗎?

http://mail-archives.apache.org/mod_mbox/openjpa-dev/200609.mbox/%[email protected]%3E

https://issues.apache.org/jira/browse/OPENJPA-235

任何人都可以說明爲什麼這不是工作,我能做些什麼呢?我不喜歡手動刪除子實體,特別是因爲這是我架構中較不復雜的關係之一,無論我使用什麼解決方案,我都需要在其他地方應用。

感謝 周杰倫

+0

你在OpenJPA有多少經驗?提交中的CascadeType有可能是錯誤的嗎? –

+0

OpenJPA?不多。我不知道在提交類中是否需要級聯定義?這是一個獨立的實體,所以如果父(複合)實體被刪除,它應該被刪除,但刪除提交不應該刪除父。就我所知,我的代碼是正確的。 –

+0

有一件事 - 如上所述,這是Weblogic 10.0.x.我懷疑我們使用的OpenJPA/Kodo的捆綁版本,這可能是相當老... –

回答

1

當我刪除複合實體的所有孩子提交實體應 也被刪除。這個工程作爲一般規則,但我對這些表一 外鍵約束設置:

如果你可以改變外鍵約束,應該儘可能的數據庫而言解決問題。我不確定OpenJPA在這裏的表現如何。

ALTER TABLE SUBMISSION 
ADD CONSTRAINT FK_SUBMISSION_COMPOUND 
    FOREIGN KEY (COMPOUNDID) 
    REFERENCES COMPOUND(COMPOUNDID) 
    ON DELETE CASCADE; 

一兩件事 - 高於此所討論的是Weblogic的10.0.x.我懷疑我們 正在使用的OpenJPA /科多獸,這可能是 很老的捆綁版本...

我自己的感覺是,你提到的臭蟲應已修復了此版本,但它也a)及時關閉,以免它可能沒有被修復,b)可能是一個足夠大的問題,我認爲你應該花一些時間來驗證版本和修復。 (實際上,我剛剛注意到OpenJPA 1.0 was released on Aug 2007,這比我想象的要早得多,這使得它更有可能沒有錯誤修復。)

如果您無法修改數據庫(因爲它是遺留系統這顯然不希望客戶依賴級聯刪除),並且如果該錯誤在您的版本中沒有修復,則必須自己管理SQL語句的順序。

手動管理SQL語句的負擔 - 這是OpenJPA應該做的的一件事 - 可能足以讓管理層升級OpenJPA或更新OpenJPA中的外鍵約束數據庫。

我真的希望你能得到比這更好的答案。

+0

嗨Catcall。我已經嘗試過了。它似乎最初工作,但後來我開始從JPA得到的錯誤消息說,子實體已被修改在事務上下文之外(我錯過了確切的錯誤信息)。此外,我有點不情願在數據庫中添加刪除級聯。 –

+0

是否由OpenJPA生成約束? –

+0

不,這是一個遺留數據庫,我正在爲它創建一個前端。這也是爲什麼我不願意添加刪除級聯條款除非絕對必要的原因之一。 –