Hibernate: лучший способ удалить элементы в коллекции
Проблема, с которой я часто сталкиваюсь с Hibernate, имеет список (вызывайте его listA) объектов, которые я хочу сохранить для объекта (myEntity), но сначала должен сравнить их с существующим списком на сущности и удалить те, которые не входят в список.
Простой способ сделать это - очистить список в Entity и просто добавить весь список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);
}
}
Есть ли возможность для улучшения?
Спасибо.
Ответы
Ответ 1
Попробуйте использовать:
myEntity.getObjectAList().removeAll(listA);
это приведет к сохранению объектов, которые еще не находятся в списке A.
Кроме того, если вам нужно сделать что-то подобное вручную в будущем, используйте итератор:
Iterator<?> it = myEntitiy.getObjectAList().iterator();
while (it.hasNext())
{
...
}
Затем it.next() предоставит вам следующий элемент в массиве, и it.remove() удалит последнее значение next() для вас, не выдавая исключения, если вы продолжаете цикл.
Если вам нужно также добавить новое значение во время цикла, попробуйте вместо этого использовать listIterator().
Ответ 2
Я знаю, что этот вопрос довольно старый, но я столкнулся с той же проблемой, и я думаю, что ответов было недостаточно. Таким образом, вы можете добиться того, что вы хотите просто добавить свойство "orphanRemoval=true"
к аннотации сопоставления. Удаление сирот происходит таким образом (как описано на странице 136 книги "Начало платформы Java EE 6 с GlassFish 3":
"[...] код автоматически удалит объект адреса при удалении клиента или когда связь будет нарушена (установив нулевой атрибут адреса или удаление дочернего объекта из коллекции в случае" один ко многим").
То есть, если вы удалите элемент из коллекции, сопоставленной с удалением сироты, а затем слейте объект, этот элемент также будет удален.