【问题标题】:Best way to replace an entity using EntityManager使用 EntityManager 替换实体的最佳方法
【发布时间】:2013-05-27 19:59:06
【问题描述】:

我正在使用 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)

现在,如果我不删除实体,而只是更新其已更改的字段,那么它当然可以正常工作。但是,我只是得到了新对象(UI 正在通过 REST 向我扔它),所以我真的不知道哪些字段发生了变化,所以我必须更新 every em> 字段。如果有很多字段,那就不太理想了。

我想我对如何正确执行删除有点困惑。我认为EntityManager.remove 是正确的方法,但我想不是。

提前致谢!

编辑 1:我觉得我应该注意 oldObject.id == newObject.id。 id 是通过@SequenceGenerator 生成的。如果对象的标识符已经用生成器注释,我是否可以使用标识符持久化对象?

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

【问题讨论】:

    标签: hibernate jpa entitymanager


    【解决方案1】:

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

    【讨论】:

    • 天哪,太尴尬了。出于某种原因,我假设merge 仅适用于附加实体,而不适用于分离实体。我想这两者都可以,对吧?无论如何,这解决了问题......我太傻了。谢谢!
    • 合并附加实体不会做任何事情,除了将合并级联到使用级联 MERGE 或 ALL 注释的关联。
    • 如果我修改附加的实体怎么办?我什至必须合并,因为它已附加?我的印象是,不,我没有。
    • 没有。 JPA 自动使附加实体的状态保持不变。因此,如果您执行attached = em.merge(detached); attached.setFoo("hello");,则数据库行的状态将为detached,除了列foo,其值为“hello”。
    • 不错。感谢您的提示!仍在学习 JPA 背后的魔力,并试图让我的大脑摆脱运行原生 Oracle SQL 脚本的根深蒂固的地位。 :P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2011-02-19
    • 2011-10-16
    相关资源
    最近更新 更多