2009-07-15 51 views
1

我有一個JPA實體「請求」,它擁有一個答案列表(也是JPA實體)。下面是它是如何在Request.java定義:爲什麼JPA在所有者實體失去對它們的引用時不刪除擁有的實體?

@OneToMany(cascade= CascadeType.ALL, mappedBy="request") 
private List<Answer> answerList; 

而且在Answer.java:

@JoinColumn(name = "request", referencedColumnName="id") 
@ManyToOne(optional = false) 
private Request request; 

在實施計劃的過程中,回答的請求的名單可能答案添加或刪除它,或者實際的List對象可能被替換。因此,我的問題是:當我將請求合併到數據庫時,使用在List中的Answer對象將保存在數據庫中 - 也就是說,請求不再持有引用的Answer對象(間接,通過列表)不會被刪除。

這不是我想要的行爲,好像我將請求合併到數據庫,然後再次獲取它,它的答案列表可能不一樣。我是否犯了一些編程錯誤?是否有註釋或設置可確保數據庫中的答案完全是請求列表中的答案?

解決方案是保持對原始Answers列表的引用,然後在合併請求之前使用EntityManager刪除每個舊的Answer,但似乎應該有一個更清晰的方法。

回答

1

在JPA 1.0中,你想做的事情不能由JPA完成。簡單地說,所有的關係管理都必須由應用程序完成,包括從集合中刪除任何孤兒(這就是你要做的)。

在JPA 2.0中,他們支持(雖然我不知道細節),但取決於您的實現,升級可能並不容易或可能。

您也可以直接使用類似Hibernate的東西,但仍然使用許多JPA 1.0註釋等。我無法提供詳細信息。

在我的情況下,我編寫了通用代碼來處理通過反射自動合併集合。

+2

在Hibernate中,這可以通過使用CascadeType.DELETE_ORPHAN來完成。 – 2010-03-02 03:19:21

0

指定映射關係中的其他屬性是非法的。 您可以在Request中使用@DependentElement批註。

+0

@DependentElement JPA規範的一部分?從來沒有跨過我的路徑.. – bert 2010-05-06 11:55:32

1

使用EclipseLink並將@PrivateOwned批註放入answerList會有所幫助。

0

如果你使用Hibernate作爲JPA提供者,你可以在answerList添加

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

。除了您已經在那裏使用的JPA批註之外,這將起作用。 JPA 2(大多數/所有JPA提供者目前沒有生產準備實施)可以自行完成。

相關問題