Подтвердить что ты не робот

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

Есть ли возможность для улучшения?

Спасибо.

4b9b3361

Ответ 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":

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

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