2011-11-23 82 views
2

我在Task和TaskError之間有一個簡單的OneToMany關係。JPA OneToMany關係不會自動填充?

任務映射TaskErrors:當任務被刪除,因此orphanRemoval

@OneToMany(cascade = CascadeType.ALL, mappedBy = "task", orphanRemoval = true) 
private List<TaskError> taskErrorCollection; 

的TaskErrors應予刪除。

TaskError連接到一個任務:

@JoinColumn(name = "task_id", referencedColumnName = "id") 
@ManyToOne(optional = false, cascade = CascadeType.ALL) 
private Task task; 

當我添加一個TaskError這個代碼不更新任務TaskErrors列表:

TaskError taskError; 
// set all taskErrors vars 
taskErrorDAO.create(taskError); 

所以數據庫包含一行TaskError,而任務中的TaskErrors列表未被填充。很明顯,當我刪除任務時,它會給出一個錯誤: MySQLIntegrityConstraintViolationException:無法刪除或更新父行

我個人需要填寫任務中的TaskError列表嗎?有沒有辦法讓這個列表自動填充? taskErrorDAO.create(taskError)之後的em.flush不起作用。

relation

回答

4

的開發商負責在內存中的實體關係的表示。所以 - 是的,你需要在TaskTaskError的列表中填寫TaskError實例。

你可以嘗試清理你PersistenceContext緩存Task並直接從數據庫中重新獲取它,所以像:

em.refresh(task); 

em.clear(); 
task = em.find(Task.class, yourTaskId); 

無論哪種方式,你的JPA提供者應該清除實體的內存中表示,按數據庫(正如您所說,已正確插入行)來獲取它並正確加載列表。不過,我不會長期從事這種方式,只是相應地更新我的對象引用。
如果您拒絕更新您的實體的內存關係,那麼您將無法使用PersistenceContext的緩存功能。爲了獲得正確的數據,您需要每次在任何新的TaskError分配給它時使用/獲取您的Task實體時都要點擊數據庫。

還有一件事 - 爲什麼你有Cascade.ALLTaskError?如果刪除TaskError,您想刪除Task實例嗎?

您還可以檢查this resource瞭解更多信息。

+0

您能否詳述一下「然而,我不會以長遠的眼光走這條路,而只是相應地更新我的對象引用。」 TaskError中的Cascade.ALL不正確,但我不確定我應該使用哪個其他設置。 TaskError刪除時不應刪除任務。 – BigJ

+0

我已經根據你的要求更新了我的答案。希望現在更清楚。如果添加了這個'Cascade.ALL'是因爲你希望TaskError被傳播到它被賦值的Task中,那麼它就行不通了。JPA明確指出,您有責任管理內存中的關係。 –

+0

我的應用程序使用大約30個關係的50個表。因此,自己更新所有關係將是巨大且容易出錯的。你說一個解決方案就是每次你想使用/獲取你的Task實體時都要打到數據庫。我可以用em.refresh(任務)? – BigJ