2012-02-29 14 views
1

オブジェクトグラフをあるデータベースから別のデータベースに移行するためのコード作業を進めています。オブジェクトグラフは構成を表しており、基本的に構成をステージング環境から運用環境に移行しています。JPA merge()の境界を設定する

グラフはソースDBからフェッチされ、分離され、シリアル化され、ターゲットDBにマージされます。

これまでのところ、これまでのところうまくいっていますが、ピックルは1つあります。

私はこのようになりますグラフがあります。UoObjectはUoAttributesのコレクションを持っており、これらのUoAttributesは別のUoObjectを参照UoAttributeObjectを有することができるので、ここで

@Entity 
class UoObject 
{ 
    @Id 
    private int uoObject; 

    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL) 
    private Set<UoAttribute> uoAttribute; 

    // Other irrelevant fields 
} 

@Entity 
class UoAttribute 
{ 
    @Id 
    private int uoAttribute; 

    @OneToOne(optional=true, fetch=FetchType.EAGER, cascade=CascadeType.ALL) 
    private UoAttributeObject uoAttributeObject; 

} 

@Entity 
class UoAttributeObject 
{ 
    @Id 
    private UoAttribute uoAttribute; 

    @ManyToOne 
    private UoObject uoObject; 
} 

を。

UoAttributeObjectsによって参照されるUoObjectsは、すでにターゲットデータベースに存在すると予想されます。もしそうでなければ、私はエラーを起こしたい。わかりやすくするために、私は決してターゲットUoObjectの状態を更新したいと思っています。基本的には、関係を設定するだけです。

これを実装したとき、カスケードなしでMERGEを指定するとJPAはオブジェクトが存在しないというエラーを発生させることが予想されました。あるいは、データベースレイヤーは、外部キーについて不平を言ってしまうでしょう。代わりに、私はJPAが大部分が空のUoObjectインスタンスを挿入しようとしていることを知っています(キーのみが設定されています)。私はJPA 2.0仕様でこれを見つけた:

Xはエンティティがカスケード= MERGEまたはカスケード= ALLが指定されていない別のエンティティY、同一の次に、ナビゲーションを参照して、「Xにマージされる場合Xからの関連付けは、ソースDBは、ターゲットがUoObjectを挿入するためのスケジュールインスタンス(悪い、そこではないことを認めると思わY.

同じ永続IDを持つ「管理対象オブジェクトYへの参照をもたらします」 )、ソースUoObjectの状態を(良い!)にマージしません。

ソースDBのエンドで、エンティティが既にDBに存在していないことを検出してエラーを発生させる方法がありますか?私はライフサイクルコールバック@PrePersistと@PreUpdateが役立つかもしれないと思うが、私はどのように見ることができない。

+0

私はこのバグに襲われたと思う:https://bugs.eclipse.org/bugs/show_bug.cgi?id=247662 – Royce

答えて

0

@VersionをUoObjectに追加するとどうなりますか?

壊れたオブジェクトグラフをマージしているため、結果を判断するのが難しい場合があります。このような状況では、ロックの使用が役立ちます。基本的には、1つのトランザクション(旧データベース)の変更をマージしている間に、オブジェクトが別のトランザクションで新しいデータベースで削除されたために状態が矛盾しているため、そのような並行性の問題を解決する唯一の方法は、ロック。

オブジェクトが存在せず、カスケードマージやカスケードが持続しない場合は、マージからエラーが発生し、無効であると思われるバグのようです。しかし、何かが新しいオブジェクトであるか、削除された既存のオブジェクトであるかを知ることは、ロックを使わなければ非常に困難です。

あなた自身だけでなく、関係をいつでも確認することができます。 UoObjectが存在する必要がある場合は、マージの前にそのオブジェクトを検索し、存在しない場合はエラーをスローするか、挿入します。

関連する問題