GSON + Hibernate:相同的对象导致“实体副本已分配给不同的实体”

2024-04-10

我有以下 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 出现异常“实体副本已分配给不同的实体”。

如果我使用不同的国家/地区,它会起作用。 如果我使用将国家/地区实例从一个对象复制到另一个对象中,这样两个子对象都引用该国家/地区的同一实例,则它会起作用。

两国都有相同的价值观。两者都有相同的 hashCode,to。 两国是平等的,但不是==,因为它们是不同的实例。

列出的提示这个问题 https://stackoverflow.com/questions/10550511/illegalstateexception-with-hibernate-4-and-manytoone-cascading没有帮助我。

我正在使用 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 会抛出异常的原因:因为它不知道该怎么做。我想说的是,您应该避免在实体图中出现相同的实例,要么干扰 GSON 的级别(它似乎也不支持这样的功能),要么在将实体图合并到数据库之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GSON + Hibernate:相同的对象导致“实体副本已分配给不同的实体” 的相关文章

随机推荐