2009-04-16 90 views
17

我經常遇到的一個問題是,Hibernate有一個對象的列表(稱爲listA),我想堅持一個實體(myEntity),但必須首先將它們與實體上的現有列表並刪除那些不在listA中的列表。休眠:刪除集合中元素的最佳方法

執行此操作的簡單方法是清除實體上的列表,然後將所有listA添加到實體中,但是我經常必須在刪除元素之前執行一些驗證操作 - 例如,檢查這個用戶是否被允許刪除它們。

我目前的做法感到尷尬:

//Delete the elements that have been removed 
//Use toArray to avoid ConcurrentModificationException 
for(ObjectA a : myEntity.getObjectAList().toArray(new ObjectA[myEntity.getObjectAList().size()])) { 
    if(!listA.contains(a)) { 

     //Check if this element can be deleted 
     if(canDelete(a)) { 
      entityManager.remove(a); 
      myEntity.getObjectAList().remove(a); 
     } 
    } 
} 

//Add the elements that don't already exist 
for(ObjectA a : listA) { 
    if(!myEntity.getObjectAList().contains(a)) { 
     myEntity.getObjectAList().add(a); 
    } 
} 

任何改進的餘地?

謝謝。

回答

10

嘗試使用:

myEntity.getObjectAList().removeAll(listA); 

這將只保留其尚未進入的listA的對象。

另外,如果你需要做這樣的事情在未來手動,使用迭代器:

Iterator<?> it = myEntitiy.getObjectAList().iterator(); 
while (it.hasNext()) 
{ 
    ... 
} 

然後it.next()會給你的數組中的下一個項目,並it.remove ()會爲你刪除next()的最後一個值,如果你繼續循環,不會發出異常。

如果您還需要在循環時添加新值的功能,請考慮使用listIterator()。

+0

我不能使用removeAll(),因爲我需要執行一些單獨的元素驗證之前刪除它們。 儘管感謝Iterator提示。 – Damo 2009-04-16 15:20:33

16

我知道這個問題是相當古老的,但我跑了同樣的問題,我認爲給出的答案是不夠的。所以,你可以在你想要的映射註釋中添加屬性"orphanRemoval=true"的確切結果。孤兒刪除以這種方式工作(如「Beginning Java EE 6 Platform with GlassFish 3」一書第136頁所述:

「[...]代碼將在客戶被移除時自動刪除Address實體,或者當關系被打破(通過設置爲null地址屬性或從集合在一到多的情況下刪除子實體)」。

也就是說,如果你從一個刪除一個項目集合映射與孤兒刪除,然後合併實體,這個項目也將被刪除