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

Jpa удаление элемента из списка

У меня есть отношение 1-N (у объекта есть список) и хочу удалить один элемент из списка. Каков правильный способ удаления элемента в списке с помощью JPA?

Должен ли я сначала обновить список и объединить владельца и удалить элемент после (если я не удалю элемент и просто слить владельца, сирота останется в БД, правильно)? В какой последовательности должны быть вызваны функции merge() и remove(), имеет ли смысл remove() и merge()?

Пример кода:

List<Item> items = owner.getItems();
Item itemToRemove = items.get(index);
owner.remove(itemToRemove);
em.merge(owner);
em.remove(itemToRemove);
4b9b3361

Ответ 1

Это должно работать, если у вас есть orphanRemoval=true (JPA 2.0).

Для JPA 1 нет стандартного способа справиться с этим. Hibernate имеет @Cascade, где вы можете указать DELETE_ORPHAN

Ответ 2

Этого достаточно:

List<Item> items = owner.getItems();
Item itemToRemove = items.get(index);
items.remove(itemToRemove);

При стирании EntityManager связь между owner и itemToRemove будет удалена. И если cascade установлен на CascadeType.ALL, itemToRemove также будет удален.

Собственно, более короткая (и эквивалентная) версия такова:

List<Item> items = owner.getItems();
// no need to keep a reference to the object that has to be removed
items.remove(index);

Справка:

Ответ 3

Спасибо, ребята, за ответы. Ваши ответы очень похожи, но есть небольшие отличия.

Просто убедитесь, что я правильно понимаю:

  • В JPA 1.0 (в общем) мне нужно вызвать remove() для ссылочных объектов. Они не будут удалены с помощью диспетчера сущностей. В противном случае сирота останется в БД.
  • В JPA 1.0 с внедрением Hibernate при установке DELETE_ORPHAN ссылочный объект удаляется с помощью диспетчера сущностей. Нет необходимости вызывать remove().
  • В JPA 2.0 (в общем случае), когда orphanRemoval = true, ссылочный объект удаляется с помощью диспетчера сущностей. Не нужно вызывать remove(). Если orphanRemoval не задано, remove() необходимо вызвать для удаления ссылочного объекта.

Ответ 4

Обычно вам не нужно ничего делать.

Если коллекция правильно отображена, вы должны вызвать items.remove(itemToRemove), и это все.

Когда вы закрываете EntityManager (это приводит к записи изменений в базу данных), он должен автоматически распознавать, что элемент был удален (потерян) от владельца и удалил его из базы данных. По крайней мере, Hibernate работает таким образом, и можно указать DELETE_ORPHAN как каскад при отображении коллекции.