скопировать дочернюю коллекцию в другой объект - PullRequest
3 голосов
/ 04 июня 2010

У меня есть отношение «один ко многим» между Частью и Параметрами («Часть» имеет много «Параметров).

Я пытаюсь сделать что-то наивное, как это:

Part sourcePart = em.find(Part.class, partIdSource);
Part destPart = em.find(Part.class, partIdDest);

Collection<Param> paramListSource = sourcePart.getParamList();

destPart.setParamList(paramListSource);

В основном я хочу скопировать все параметры из sourcePart в destPart. Надеемся, что поставщик сохраняемости автоматически установит правильные внешние ключи в таблице / сущности Param.

Код выше, очевидно, не будет работать.

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

Редактировать

Сначала я попытался отсоединить сущность, как это рекомендовано в другом потоке, но я получил исключение (org.hibernate.PersistentObjectException: отсоединенная сущность передана в persist: shared.entity.Param).

Part sourcePart = em.find(Part.class, partIdSource);
// force eager loading...
((List)sourcePart.getParamList()).get(0);

Part destPart = em.find(Part.class, partIdDest);

// detach entity
org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();
session.evict(sourcePart);

//causes exception "detached entity passed to persist"
destPart.setParamList(sourcePart.getParamList());

Ответы [ 3 ]

2 голосов
/ 04 июня 2010

В основном я хочу скопировать все параметры из sourcePart в destPart. Надеемся, что поставщик сохраняемости автоматически установит правильные внешние ключи в таблице / сущности Param.

Если вы хотите пойти «путем выселения», сделав свои сущности Отделенными , то НЕ достаточно, вам необходимо «обнулить» свойства Id, чтобы ваши сущности стали Новый снова (сохранение их должно привести к SQL INSERT). В псевдокоде:

MyObject ob = session.get(idOfExisting);
hibernate.evict(ob);
ob.setId(null);
hibernate.save(ob);

Но я нахожу это грязным. Я бы перебрал элементы списка и использовал бы конструктор копирования (без копирования свойств Id), чтобы создать новый список, а затем установить копию для целевого объекта (и это было бы независимым от поставщика).

1 голос
/ 04 июня 2010

Я почти уверен, что на самом деле вы получаете не экземпляры Param, а прокси-объекты, которые реализуют интерфейс Param, поэтому вам, возможно, придется создавать новые объекты Param и копировать свойства. Кроме того, не отсоединяйте их от сеанса, поскольку, если они являются прокси-серверами, они не смогут получить другие свойства, кроме Id, который является единственным заполненным изначально (отложенная выборка).

1 голос
/ 04 июня 2010

Может быть, вы можете реализовать метод clone() в Param. Тогда вы могли бы сделать paramListSource.clone().

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