mak*_*enz 9 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的异常"实体副本已经分配给不同的实体".
如果我使用不同的国家,它就有效.如果我将国家实例从一个对象复制到另一个对象,则它可以工作,因此两个子对象都引用该contry的相同实例.
这两个国家都有相同的价值观.两者都具有相同的hashCode.这两个国家是平等但不是==,因为它们是不同的实例.
这个问题上列出的tipps对我没有帮助.
我正在使用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)
    [...]
如何以通用方式解决此问题我不需要知道对象类型和哪些对象在逻辑上相同?
小智 2
这是我不使用合并的工作解决方案:
我使用反射在绑定时迭代字段。我检查该字段是实体还是实体集合,然后如果 json 中提供了 id,则调用 findByID;如果不获取附加实体,则创建该实体的新实例。之后,我通过反射将 json 中存在的字段值复制到附加实体中。我递归地执行此操作来处理实体之间的关系。之后,我就有了实体的完全合并和附加版本以及所有附加和合并的子对象。我可以毫无问题地保存它
重要的提示:
Andrei 我提出了很多可能发生的逻辑问题,并更改 api 以获得完整的国家/地区,但只是它们的 ID 会更清晰。我更喜欢这个,并且将来也会这样做。因此安德烈我赢得了赏金。
| 归档时间: | 
 | 
| 查看次数: | 7079 次 | 
| 最近记录: |