我有一個實體Task和一個道具:TaskDao。任務實體具有到類別的ManyToOne映射。當我刪除任務,我還需要從集合中刪除的任務類別:以正確的方式刪除實體和關係(JPA)
// remove() method in TaskDao
public void remove (Task p_task) {
// p_task is Detached, p_task.getCategory() is Detached
p_task = em.merge(p_task);
// p_task is Attached, p_task.getCategory() is Attached
em.remove(p_task);
// p_task is Detached, p_task.getCategory() is Attached
p_task.getCategory().removeTask(p_task);
}
評論表明(在這一點),如果P_TASK和/或p_task.category的安裝/拆卸。首先讓我解釋一下爲什麼我選擇這個順序。首先,我需要合併p_task,以便p_task.category被附加,並且爲了移除它需要合併的p_task。因爲em.remove(p_task)可以拋出ConstraintException,所以p_task從類別集合中被移除,這種情況下不應該從類別集合中刪除該任務。
這是正確的認同?另外,在em.remove(p_task)之後,我仍然感到驚訝,p_task.category仍然存在。
編輯:我應該從實體類中提供一些代碼。
public class Task implements Serializable {
@JoinColumn(name = "category_id", referencedColumnName = "id")
@ManyToOne(cascade = CascadeType.MERGE, optional = false)
private Category category;
}
public class Category implements Serializable {
@OneToMany(cascade = CascadeType.MERGE, mappedBy = "category")
private List<Task> taskCollection;
public void addTask (Task p_task) {
if (taskCollection == null) {
taskCollection = new ArrayList<>();
}
if (!taskCollection.contains(p_task)) {
taskCollection.add(p_task);
}
}
public void removeTask (Task p_task) {
taskCollection.remove(p_task);
}
}
在下面的代碼P_TASK從category.taskCollection去除,而事務回滾:
// remove() method in TaskDao
public void remove (Task p_task) {
p_task = em.merge(p_task);
p_task.getCategory().removeTask(p_task); // will not be rolled back if em.remove(p_task) throws an exception
em.remove(p_task);
}
1.但p_task.getCategory()。removeTask(P_TASK)語句不會回滾,對不對?這會在數據庫和內存數據之間留下不一致。 2.當我刪除任務時,我不想刪除關聯的類別。我確實希望從category.taskCollection中刪除已刪除的任務。 – BigJ
如果回滾事務,則在事務期間完成的每個修改都會回滾。如果關閉會話,它在內存中保存的每個實體都會被分離,並且必須被視爲不一致。你必須忘掉它們。 –
我使用CMT,所以我自己實際上並不控制事務。你會建議在調用em.remove()之前刪除內存中的引用嗎? – BigJ