hibernate - GSON + hibernate : Identical objects causing "An entity copy was already assigned to a different entity"

标签 hibernate jpa gson

我有以下JSON:

{
    id: 123,
    subObjects: [
        {
            id: 564,
            name: "foo",
            contry: {
                id: 1,
                name: "Germany"
            }
        },
        {
            id: 777,
            name: "bar",
            contry: {
                id: 1,
                name: "Germany"
            }
        }
    ]   
}

并使用Gson反序列化它。之后,我需要合并JPA实体:
Model model = new Gson().fromJson(json, modelClass);
model = entityManager.merge(model)

刷新从模型级联到子对象,再级联到各个国家/地区。
这会导致Hibernate出现异常“已将实体副本分配给其他实体”。

如果我使用其他国家/地区,则可以使用。
如果我使用将国家/地区实例从一个对象复制到另一个对象,则两个子对象都引用该对象的同一实例,则该方法有效。

两国具有相同的值(value)观。两者也具有相同的hashCode。
两国是平等的,但不是==,因为它们是不同的情况。

this question上列出的小费对我没有帮助。

我正在使用Hibernate 4.1.3 Final和Gson 2.2
java.lang.IllegalStateException: An entity copy was already assigned to a different entity.
    at org.hibernate.event.internal.EventCache.put(EventCache.java:184)
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:285)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
    at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
    at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
    at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
    at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:904)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:888)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:892)
    at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:874)
    at play.db.jpa.GenericModel.merge(GenericModel.java:234)
    [...]

我该如何以通用方式解决此问题,而无需知道对象类型以及哪些对象在逻辑上是相同的?

最佳答案

我认为这种行为完全超出了JPA或Hibernate的范围,这就是Hibernate抛出该Exception的原因:因为它不知道该怎么办。我想说的是,您应该避免实体图中出现相同的实例,要么干扰GSON的级别(这似乎也不支持这种功能),要么就在将实体图合并到DB中之前。

关于hibernate - GSON + hibernate : Identical objects causing "An entity copy was already assigned to a different entity",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20146829/

相关文章:

java - Gson 在 "$Types.resolve"上溢出并出现 StackOverflow 异常

java - 使用 gson 将 JSON 转换为 java 对象

java - 使用 Spring 和 Hibernate 创建新项目

java - 理解 `Pro JPA 2 Mastering the java Persistence API` 中的一段话吗?

java - Spring 数据存储库 : Detached entity passed to persist

java - 当我有私有(private) id 字段时,为什么 Hibernate 要求我们实现 equals/hashcode 方法?

java - 在persistence.xml 的jta-data-source 中放入什么?

java - Gson Instance Creator 创建了实例,但字段为空

java - Hibernate 可以将列的子集映射到内部子 Pojo 中

java - 如何加载持久的 Hibernate 实体进行绑定(bind),以便非表单属性不会丢失?