使用EntityManager替换实体的最佳方法

时间:2013-05-31 22:07:27

标签: hibernate jpa entitymanager

我正在使用JPA EntityManager来执行某些操作,其中一个操作是将实体替换为具有相同@Id的另一个实体。那么,给定oldObjectnewObject,删除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.id == newObject.id。 id是通过@SequenceGenerator生成的。如果标识符已经用生成器注释,我是否可以使用标识符来持久保存对象?

编辑2:根据热门评论的答案here,因为@Id已经定义并且它是一个自动生成的字段,所以Hibernate认为它已经分离了。现在我知道为什么我得到了例外,但解决方案仍然不清楚。

1 个答案:

答案 0 :(得分:5)

这就是EntityManager.merge()的作用。将它传递给新的,分离的实体,它将其状态合并到旧的附加实体。分离的实体将保持独立状态,旧的实体将保持连接状态,但其状态将被新的独立状态替换。