2017-01-18 7 views
2

いくつかのパフォーマンスの問題をトラブルシューティングしていますが、Hibernateが親IDを更新するN + 1問合せを生成している子エンティティではHibernate/JPAでN + 1問合せを親IDで更新する方法

私はこのようなコード持ってSpring 4.3.4Hibernate 5.2.5、およびSpring Data 1.10.5

を使用しています:

Parent p = createParent(); 
Parent savedParent = parentRepo.save(p); 
savedParent.addChild(new Child()); 
savedParent.addChild(new Child()); 
savedParent.addChild(new Child()); 
parentRepo.save(savedParent); 

問題は、それがこのようなSQLを生成していることである:

insert into parent (col1, col2, col3) values (1,2,3) 
insert into child (col1, col2, col3, parent_id) values (1,2,3, PARENT_ID), (1,2,3, PARENT_ID), (1,2,3, PARENT_ID) 
update child set parent_id = PARENT_ID where id = x 
update child set parent_id = PARENT_ID where id = x+1 
update child set parent_id = PARENT_ID where id = x+2 

私のマッピングをこのように見える

Parent{ 
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 
    @JoinColumn(name = "parent_id", nullable = false) 
    @BatchSize(size = 500) 
    private List<Child> items; 
} 

Child{ 
    @ManyToOne(optional = false) 
    @JoinColumn(name = "parent_id", referencedColumnName = "id", nullable = false, insertable= false, updatable = false) 
    private Parent parent; 
} 

私は子供を追加する前にIDを持っていることを確認し、最初に親を保存せずに大量の保存を行うだけで親を保存するのが面倒ですが、常にN + 1クエリを生成します。私はちょうどそれが親であることを知っていることを確認するために、コード内の子にインベントリを設定していることを確認しましたが、それはまた助けには見えませんでした。私のグーグル・グーグルでは、ほとんどのタイプのN + 1問合せを回避する方法について説明しますが、この特定のタイプはサポートしていません。挿入に親IDを正しく設定しているために、親IDが正しく設定されていても、それが変更されていなくても、更新する必要があるので、奇妙です。

+0

を働いていました!? – Strawberry

答えて

2

mappedBy属性を追加した以下のコードを試してください。これは、オブジェクトグラフで設定しているが、休止状態の関係には反映されていない単純な双方向マッピングの場合です。

Parent{ 
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true,mappedBy="parent") 
@JoinColumn(name = "parent_id", nullable = false) 
@BatchSize(size = 500) 
private List<Child> items; 
} 
1

私はそれが働いて、私はこれに私のマッピングを変更しなければならなかったてしまった:

Parent{ 
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent") 
    @BatchSize(size = 500) 
    private List<Child> items; 
} 

Child{ 
    @ManyToOne(optional = false) 
    @JoinColumn(name = "parent_id", referencedColumnName = "id", nullable = false) 
    private Parent parent; 
} 

その後、すべてがどのようにそれがベースid値を知っているん

+0

あなたが私の答えを受け入れることができればそれは役に立ちます:) –

関連する問題