2015-04-26 38 views
4
正確

我有很多一對多的關係,在我的數據庫(實體是參與者和事件)不是很瞭解如何刪除字段與Hibernate

//part of participant model 
@ManyToMany(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST, CascadeType.MERGE}) 
    @JoinTable(name = "participant_event", 
      joinColumns = {@JoinColumn(name = "participant_id")}, 
      inverseJoinColumns = {@JoinColumn(name = "event_id")}) 

//part of event model 
    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "events", cascade = CascadeType.ALL) 

就在這一刻,刪除事件導致刪除所有參加此次活動的參與者。事件模型中刪除CascadeType.ALL在刪除事件後不會導致任何結果(刪除我的意思是.remove)。什麼是正確的方法來刪除事件,並保留所有參與者?

代碼爲here

+1

刪除級聯應至少導致刪除SQL查詢被執行。它可能會失敗,從而導致拋出異常,因爲參與者仍然引用被刪除的事件。治療很簡單:從所有參與者中刪除事件,並刪除事件。 –

+1

在刪除事件之前調用'flush()'。這會迫使Hibernate從連接表中刪除,然後再從事件表中刪除。 –

+0

@JBNizet現在注意到了奇怪的事情 - 我用'event_id = 1','flush()'清除了字段中的participant_event表,嘗試'.remove(event)'id = 1並且它說'Key(event_id )=(3)仍然參考table participant_event'(而不是'event_id = 1' !!)。但是,如果我'返回事件;'從函數返回只有一個事件'event_id = 1'它可以是FetchType的東西嗎? –

回答

2

在許多-to-many關聯,CascadeType.REMOVE is not desirable,因爲它會刪除實際的實體(而不只是他們相關的鏈接表項)。

刪除關聯的正確方法是分離的實體:

public void removeEvent(Event event) { 
    events.remove(event); 
    event.setParticipant(null); 
} 

要刪除Event,你必須從所有Participants刪除。爲此,你必須這樣做:

Event deletableEvent = ...; 

for(Iterator<Participant> participantIterator = event.getParticipnts(); participantIterator.hasNext();) { 
    Participant participant = participantIterator.next(); 
    participant.getEvents().remove(deletableEvent); 
    participantIterator.remove(); 
} 

entityManager.flush(); 
entityManager.remove(deletableEvent); 
+0

.remove(event)導致關於仍然存在的引用的相同異常(如果我有你的權利,我們從EntityManager中調用此方法) –

+0

檢查我更新的答案 –

+0

看起來像現在我正在做那件事,但由於某種原因' .remove()'試圖刪除不是我試圖刪除的唯一事件。檢查我的意見以回答問題 –