2009-04-16 3 views
17

Проблема, с которой я часто сталкиваюсь с Hibernate, имеет список (называть его listA) объектов, которые я хочу сохранить в сущности (myEntity), но сначала их сравнить с существующий список на объекте и удалить те, которые не входят в списокA.Спящий режим: лучший способ удалить элементы в коллекции

Простой способ сделать это - очистить список объектов и просто добавить весь списокA в объект, однако мне часто приходится выполнять некоторую проверку элементов перед их удалением - например. чтобы проверить, разрешено ли этому пользователю удалять их.

Мой текущий подход чувствует себя неловко:

//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); 

это будет только держать предметы, которые не являются уже в lišta.

Кроме того, если вам нужно сделать что-то вроде этого вручную в будущем использовать итератор:

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

Тогда it.next() даст вам следующий элемент в массиве, и it.remove() удалит последнее значение next() для вас, не выдавая исключения, если вы продолжаете цикл.

Если вам нужно также добавить новое значение во время цикла, попробуйте вместо этого использовать listIterator().

+0

Я не могу использовать removeAll(), поскольку мне нужно выполнить некоторую проверку по отношению к элементам отдельно до удаляя их. Спасибо за наконечник Итератора. – Damo

+2

Я думаю, что точка removeAll заключалась в том, что он обрезает список на вашем объекте до тех, которые вам нужно проверить на удаление. Затем вы проверяете все и удаляете, если разрешено. Затем вы можете добавить все listA, не проверяя, есть ли они там, потому что вы уже удалили их. – digitaljoel

16

Я знаю, что этот вопрос довольно старый, но я столкнулся с той же проблемой, и я думаю, что ответов было недостаточно. Таким образом, вы можете достигнуть именно того результата, который хотите просто добавить свойство "orphanRemoval=true" к вам, отображающему аннотацию. Таким образом, удаление сирот происходит (как описано на странице 136 книги «Начало платформы Java EE 6 с GlassFish 3»:

«[...] код автоматически удалит объект« Адреса »при удалении клиента, или когда связь нарушена (путем установки нулевого атрибута адреса или путем удаления дочернего объекта из коллекции в случае «один ко многим»).

То есть, если вы удалите элемент из коллекция, сопоставленная с удалением сироты, а затем слияние объекта, этот элемент также будет удален.

Смежные вопросы