2017-11-03 3 views
1

を標準012EEエンジンとして使用し、エンティティツリーはCascadeType.ALLの注釈付きのすべてのエンティティにOneToManyの関係があります。すべてのエンティティは、データベースシーケンスからの@GeneratedValueのIDを持ちます。Eclipseエンティティツリーを再接続した後で奇妙な動作をします

トランザクション中にエンティティツリーのマネージインスタンスをフェッチした後、ルートをデタッチし、ヌルをすべて@Idフィールドと@Versionフィールドに設定し、ルートエンティティをマージします。

ツリー内のすべての管理対象エンティティは、2つを除き、新しいIDを持つことが予想されます。主に関する避けるために、私はそのエンティティA内のequalsとhashCodeメソッドでいくつかの変更を試みた

org.eclipse.persistence.exceptions.ValidationException 
Exception Description: Null or zero primary key encountered in unit of work clone [EntityA [id=null, businessId=17EN000000000083]], primary key [null] 

:問題は、異なるタイプの2つのエンティティが自分のIDフィールドにヌルを保持し、私は次の例外を取得していますコミットするときにということです2つのエンティティは、両方のIDがnullの場合は同じですが、何も起こりません。この動作は決定的ではなく、デバッグ中にIDが生成されることもありますが、通常はnullです。

誰でも問題のヒントを教えてください。

--edit

我々は問題の関係でFetchType.EAGER代わりのFetchType.LAZYを使用すると、予想通り、mergeはIDを作成しました。誰もがなぜこれが起こるか説明できますか?

+0

既存のツリーを複製しようとしている場合は、新しいコピーを作成するためのクローンメソッドを実装しないでください。それ以外の場合は、問題のエンティティをグラフではなく直接マージ(または、より良い意味で永続化)すればどうなりますか? – Chris

+0

私はエンティティツリーの新しいバージョンを作成しようとしています。 IDを分離して設定すると、各エンティティのバージョン番号が増えます。クローンを使用する場合は、ツリーのすべてのエンティティを手動でクローンする必要があります。カスケードを切り離すと、ルートエンティティを切り離し、変更後にマージします。日食リンクのアイデンティティマップに関連する何かが問題を引き起こしているようです。問題のあるエンティティを分離して新しいものを作成し、それを永続させると、すべて正常に動作します。エンティティが既にキャッシュに存在する場合、マージ中にEclipseリンク・エンティティ・マネージャがどのようにチェックするかは誰にも分かりますか? –

+0

これは、EclipseLinkが変更トラッキングを使用している環境では間違って作成されています。既存のものを再利用するだけでなく、PKを変更するだけでなく、エンティティのコピーを作成する必要があります。試してみるか、私が提案したようにオブジェクトを直接永続化してみてください。あなたが見ている振る舞いは、あなたの怠惰な関係があなたの「分離」の前に取り出されなかったならば簡単に説明できます。あなたがこれらの存在をどのように切り離しているのか説明しませんでした。 EclipseLinkでは、読んでいたコンテキストがまだ利用可能である限り、遅延関係にアクセスすることができるため、その関係にアクセスすることは管理対象エンティティを読み取ることです。 – Chris

答えて

0

エンティティをシリアル化していない限り、実際にはデタッチされません。 EclipseLinkには、文脈がまだ利用可能である限り、遅延関係を取得できる機能があります。これは、EntityManagerFactoryが閉じられるか、エンティティがシリアル化されるまで意味します。したがって、あなたのエンティティを「切り離して」、怠け者で足かせていない関係をトラバースすると、参照されたエンティティは、最初の読み込みを実行したEntityManagerから読み込まれ、管理されます。

それにかかわらず、他のアーティファクトを追跡する変更がエンティティに織り込まれるため、新しいIDでデータを保持したい場合は、エンティティをコピーする方がよいでしょう。

関連する問題