2017-09-26 5 views
0

私はデータモデル内でOneToOne関係を持っており、hibernateは常に結果セットを生成するために両方のエンティティをクエリしています。Hibernateは常に冗長クエリを実行しています

このデータモデル

@Entity 
public class C1 { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, optional = false, targetEntity = C2.class) 
    private C2 c2; 

    //... other stuff 
} 


@Entity 
public class C2 extends OtherClassOutOfDomain { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "c2") 
    private C1 c1; 

    //... other stuff 
} 

Hibernateは二つのテーブルとC1テーブルとして私のスキーマを生成されたが、私はC1を使用して、より頻繁になりますように私に最適です何を、C2への外部キーを持っています。私はC1の照会

BUT

毎回行あたり両方のエンティティのデータを結合する1つのクエリを生成し、第1の結果のすべての行のN個のクエリを生成休止状態(I、結果セットにアクセスする前であっても)

Hibernate (just one): 
    select 
     this_.id as id1_2_1_, 
     this_.c2_id as authDat22_2_1_, 
     this_.bio as bio2_2_1_, 
     this_.blocked as blocked3_2_1_, 
     this_.commentsAmount as comments4_2_1_, 
     this_.confirmed as confirme5_2_1_, 
     this_.deleted as deleted6_2_1_, 
     c22_.id as id1_0_0_, 
     c22_.adid as adid2_0_0_, 
    from 
     c1 this_ 
    inner join 
     c2 c22_ 
      on this_.authData_id=c22_.id 

Hibernate (N times as the size of previous query): 
    select 
     this_.id as id1_2_1_, 
     this_.c2_id as authDat22_2_1_, 
     this_.bio as bio2_2_1_, 
     this_.blocked as blocked3_2_1_, 
     this_.commentsAmount as comments4_2_1_, 
     this_.confirmed as confirme5_2_1_, 
     this_.deleted as deleted6_2_1_, 
     c22_.id as id1_0_0_, 
     c22_.adid as adid2_0_0_, 
    from 
     c1 this_ 
    inner join 
     c2 c22_ 
      on this_.authData_id=c22_.id 
    where 
      this_.authData_id=? 
.....repeat 
.....repeat 
.....repeat 

繰り返しクエリの結果は、最初の大きなクエリの行にcointainedさ...これらに、不要なリクエストを避けるためにどのような方法はありますか?私はそれがdidn't作品は、ネストされたクエリをトリガーする前に、私も結果にアクセスしていないよ、私はこの動作を取得するために実行しているコードは

HibernateUtils.createNewSession().createCriteria(C1.class).list(); 

簡単です

として怠惰に設定しようとしたが、

私は休止状態を使用しています5.10 e mysql 5.7.17

+0

オプション= falseの?本当に試してください –

答えて

0

私は解決策を得ましたが、なぜ私は完全に理解できませんでした。 JPAとのマッピングOneToOne関係として

休止状態は、エンティティによって照会ながら "targetEntity" 属性(ATRIBUTE VALUE属性でNO THE ENTITY SETTED WITH ENTITY)

を持っているエンティティに外部キーを配置しますその構造の休止状態で外部キーが自動的に

は、私の以前の関連する問題を解決するために(私はその理由を知らない)ネストされたエンティティを照会しています、私はちょうどに注釈を変更するために必要な

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, optional = false, mappedBy= "c1") 
private C2 c2; 

@OneToOne(fetch = FetchType.LAZY, targetEntity = C1.class) 
private C1 c1; 
0

この2つのことをあなたの心に留めてください。

OneToOneのデフォルトフェッチ戦略はEAGERです。

LAZYは、関連付けがNULLでない場合のみ、OneToOneの関連付けで機能します。

HQL

どちらか から

C1 C1の が参加左参加フェッチ:

あなたの問題は、N + 1を選択の問題に似ている

解決N + 1は、問題が選択します c1を取得します。C2

または

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, optional = false, mappedBy= "c1") 
@Fetch(FetchMode.JOIN) 
private C2 c2; 

と第二のクラスの

@OneToOne(fetch = FetchType.LAZY, mappedBy = "c2") 
@Fetch(FetchMode.JOIN) 
private C1 c1; 
関連する問題