「実体のコピーは既に別のエンティティに割り当てられていた」: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によって "エンティティコピーがすでに別のエンティティに割り当てられています"という例外が発生します。
私は異なる国を使用する場合に機能します。 両方のサブオブジェクトがそのコンテンションの同じインスタンスを参照するように、1つのオブジェクトから別のオブジェクトへcountryインスタンスをコピーすると機能します。
両方の国で同じ値が設定されています。両方とも同じhashCodeを持ちます。 両国は同じですが、異なるインスタンスであるため==ではありません。
this questionに記載されているtippsは私を助けませんでした。
私は、Hibernate 4.1.3私は、私はオブジェクトの種類を知っている必要はありませんし、そのオブジェクトは、論理的に同一であり、一般的な方法でこの問題を解決するにはどうすればよい
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.2決勝とGson
を使用していますか?
@AndreiI使用しているフレームワーク(再生1.2.x)は、使用するパッチによって特定のバージョンが必要なため、アップグレードはオプションではありません。私は本当にそれを一般的な方法で解決する必要があります。なぜなら、私は異なるエンティティで同じケースを持っているからです。大きなオブジェクトをWebサーバーからmvc-javascriptフレームワーク(AngularJS)にトランスポートして、サーバ。オブジェクトは複雑な企業データを表現しています。 – maklemenz
同じIDを持ち、名前の異なる2つの国が来たときに、どのような振る舞いになると思いましたか?この質問だけでは答えにくいので、インターフェースからすべてを受け入れるのではなく、IDをロードするDTOを使用するように提案します。また、おそらくあなたはあまりにも多くのユーザーインターフェイスを信頼しています。既存のIDを持つ国またはそのインタフェースで使用することが許可されていない国を追加することを考えるだけです。つまり、データをDBでマージするのではなく、データを検証する必要があります。 –
このアプリケーションのユーザーは、通常とは異なる方法でデータを変更するために必要な知識がなくても、100%信頼できる管理ユーザーですが、検証が必要です。私のケースでは、彼らはcontriesを変更する必要はありませんが、彼らは正しいものを選択する必要があります。他のケースは、実装するためにはるかにコンパイルされているかもしれません。私のケースでは、おそらくそのオブジェクトのcontriesのIDを取得するenougthと休止は、残りの部分を行うことができますが、彼らは同じインスタンスの場合のみ。 – maklemenz