オブジェクトグラフをあるデータベースから別のデータベースに移行するためのコード作業を進めています。オブジェクトグラフは構成を表しており、基本的に構成をステージング環境から運用環境に移行しています。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が役立つかもしれないと思うが、私はどのように見ることができない。
私はこのバグに襲われたと思う:https://bugs.eclipse.org/bugs/show_bug.cgi?id=247662 – Royce