Лучший способ заменить объект с помощью EntityManager


Я использую JPA EntityManager для выполнения некоторых операций, и одна из таких операций заключается в замене сущности другой сущностью, имеющей тот же @Id. Итак, учитывая oldObject и newObject, каков наилучший способ удалить oldObject и заменить его newObject?

Вот код, который не работает:

try
{
    entityManager.getTransaction().begin();
    entityManager.remove(oldObject);
    entityManager.persist(newObject);
    entityManager.getTransaction().commit();
}
catch (PersistenceException persistExc)
{
    entityManager.getTransaction().rollback();
    // do some stuff
}

Этот код получает следующее исключение:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.depressio.SomeObject
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678)

Теперь, конечно, это работает нормально, если вместо удаления сущности я просто обновляю ее поля, которые изменились. Однако мне просто дают новый объект (пользовательский интерфейс бросает его мне через REST), поэтому я действительно не знаю, какие поля изменились, поэтому мне придется обновить каждое поле. Если есть тонна полей, это не идеально.

Я думаю, что немного запутался в том, как на самом деле правильно сделать удаление. Я думал, что EntityManager.remove был правильный путь, но я думаю, что нет.

Заранее спасибо!

Редактировать 1: я чувствую, я должен отметить, что oldObject.идентификатора == переменная newobject.ИД. В id является генерируется через @SequenceGenerator. Можно ли сохранять объекты с идентификаторами, если их идентификатор уже аннотирован генератором?

Edit 2: Согласно ответу сверху здесь , поскольку @Id уже определено и это автоматически генерируемое поле, Hibernate считает его отделенным. Теперь я знаю, почемуя получаю исключение, но решение все еще неясно.

1 5

1 ответ:

Именно это и делает EntityManager.merge(). Передайте ему новую, обособленную сущность, и он сольет свое состояние со старой, присоединенной сущностью. Обособленная сущность останется обособленной, а старая останется привязанной, но ее состояние будет заменено состоянием новой, обособленной сущности.