Hibernate: лучший способ удалить элементы в коллекции - PullRequest
17 голосов
/ 16 апреля 2009

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

Простой способ сделать это - очистить список в Entity и просто добавить весь 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);
    }
}

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

Спасибо.

Ответы [ 2 ]

19 голосов
/ 13 мая 2011

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

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

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

11 голосов
/ 16 апреля 2009

Попробуйте использовать:

myEntity.getObjectAList().removeAll(listA);

это сохранит только те объекты, которых еще нет в списке A.

Также, если вам понадобится сделать что-то подобное в будущем вручную, используйте итератор:

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...