2016-07-18 7 views
1

私はSOを検索し、これに対して適切な解決策を見つけられませんでした。私は親エンティティを持っていると言う:春JPAの新しい子エンティティの親エンティティ

@Entity 
public class Parent { 
    @Id 
    @GeneratedValue 
    private int id; 

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) 
    private List<Child> childList; 
} 

と親エンティティに関連する外部キーを持っている子エンティティ、:

@Entity 
public class Child { 
    @Id 
    @GeneratedValue 
    private int id; 

    @JoinColumn(name = "parentId") 
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
    private Parent parent; 

}

私のシナリオは少し特殊です。子エンティティは1時間に膨大な量で生成され、データベースに保存する必要があります。これらの子オブジェクトは同じ親を持ち、関連親エンティティはすでにデータベースに存在している可能性があります。私の要件は、entityManagerからマネージ親エンティティを問合せせずにこれらの子オブジェクトをすべて保存することです。親エンティティが存在する場合は、既存のエンティティをマージ/更新するだけです。例:

Child c = new Child(); 
// set some properties of child 
Parent p = new Parent(); 
// set some properties from my data into the parent. The parent may already exists 
child.setParent(p); 
JpaRepo.saveAndFlush(child);// If parent already exists, merge with the existed parent object, otherwise, create new parent object. 

明らかにこれは機能しません。親エンティティが存在しない場合、親エンティティを正しく作成して関連付けます。しかし、親がすでに存在する場合、重複キーに関する例外がスローされ、親のId(ダミー値を使用して強制的にマージを行う)を設定すると、分離されたエンティティオブジェクトの例外がスローされます。

パフォーマンス制約のため、あまりにも多くのものがあるので、私はデータベースから親エンティティを読み込むことができません。したがって、プライマリキーが違反したときにオブジェクトをマージするJPAまたはデータベースを自動的に作成する方法はありますか?

私はMySQLを使用していますが、重複したキー更新を使用することは可能ですか?

+0

保存する前に、子オブジェクトで使用可能な親のIDがありますか? –

+0

いいえ、私はidを持っていませんが、代わりに、オブジェクトを識別するためのユニークなキーとして使用できるすべての属性を持っています。 – LynxZh

答えて

0

これは、達成したいと思うややこしいスタッフです。遅延ロードなどは、(私が好む)オプションではない場合、私はあなたにお勧め別のエンティティの作成:あなたは親オブジェクトが存在するかどうかを確認し、あなたの追加の子を保存するためにChildSaveObjectを使用する必要があります。このフローでは

@Entity 
@Table(name = "sameAsTheOriginal") 
public class ChildSaveObject { 
    @Id 
    @GeneratedValue 
    private int id; //I think int will run out fast if there are a lot of objects but it is your choice. (Int max value: 2 147 483 647 is not that mutch) I prefer Long az id 

    @Column(name = "parentId") 
    private int parent; //note that You need to have the id of the parent object 

    //Other properties... 
} 

をそれに。

ほとんどの場合、1対多のマッピングが大好きではありません。問題の根源に過ぎないと思います。それでもやりたいのであれば、fetch = FetchType.LAZYを使用し、親エンティティを取得することが推奨されます(この方法では、不要な子をすべて読み込むことはできません)。

+0

私は親から子をロードしません。問題は、新しい子を作成して既存の親に関連付ける必要があることです。存在しない場合は新しい親を作成します。 – LynxZh

+0

これは、親が存在するかどうかをチェックする理由です。クエリを実行して親を取得し、存在しないものが作成された場合は、最小化されたものを設定します。 – Mark

関連する問題