2011-11-30 92 views
1

我有一個實體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); 
} 

回答

2

這是確定的,據我所知。但是,您有一些不正確的假設:

  1. em.remove(p_task)不會拋出ConstraintException。清除od將被刪除。如果拋出此異常,唯一要做的就是回滾事務並關閉實體管理器,因爲它會使其處於不一致的狀態。因此,在從類別中刪除任務之前或之後刪除任務並沒有太大的區別。
  2. 您刪除任務,但不刪除該類別。那爲什麼這個類別還沒有被附加?
+0

1.但p_task.getCategory()。removeTask(P_TASK)語句不會回滾,對不對?這會在數據庫和內存數據之間留下不一致。 2.當我刪除任務時,我不想刪除關聯的類別。我確實希望從category.taskCollection中刪除已刪除的任務。 – BigJ

+0

如果回滾事務,則在事務期間完成的每​​個修改都會回滾。如果關閉會話,它在內存中保存的每個實體都會被分離,並且必須被視爲不一致。你必須忘掉它們。 –

+0

我使用CMT,所以我自己實際上並不控制事務。你會建議在調用em.remove()之前刪除內存中的引用嗎? – BigJ

1

它是正確的答案。您必須從集合中刪除任務以確保集合的功能。

也許檢查P_TASK被合併前,如果真的任務分離Ç