2016-05-26 9 views
0

を打つ左結合:Hibernateはいつも、私は次のサービス持っているベース

Check 1 
2393 [main] INFO org.hibernate.hql.internal.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory 
Check 2 
2547 [main] DEBUG org.hibernate.SQL - select distinct house0_.ID as ID1_1_, house0_.FK_K_LSK as FK_K_LSK2_1_, house0_.FK_STREET as FK_STREET3_1_ from AR.HOUSE house0_ left outer join AR.KW kw1_ on (house0_.ID=kw1_.FK_HOUSE)left outer join AR.KART kart2_ on (kw1_.ID=kart2_.FK_KW)left outer join PS.REG reg3_ on (kart2_.LSK=reg3_.LSK)left outer join PS.REG_STATE regstate4_ on (kart2_.LSK=regstate4_.LSK) where house0_.FK_K_LSK=187804 
Check 3 
2609 [main] DEBUG org.hibernate.SQL - select kw0_.FK_HOUSE as FK_HOUSE3_3_0_, kw0_.ID as ID1_3_0_, kw0_.ID as ID1_3_1_, kw0_.FK_K_LSK as FK_K_LSK2_3_1_, kw0_.FK_HOUSE as FK_HOUSE3_3_1_ from AR.KW kw0_ where kw0_.FK_HOUSE=? 
2655 [main] DEBUG org.hibernate.SQL - select kart0_.FK_KW as FK_KW4_2_0_, kart0_.LSK as LSK1_2_0_, kart0_.LSK as LSK1_2_1_, kart0_.FK_K_LSK as FK_K_LSK2_2_1_, kart0_.FIO as FIO3_2_1_, kart0_.FK_KW as FK_KW4_2_1_ from AR.KART kart0_ where kart0_.FK_KW=? 
2657 [main] DEBUG org.hibernate.SQL - select reg0_.LSK as LSK6_15_0_, reg0_.ID as ID1_15_0_, reg0_.ID as ID1_15_1_, reg0_.DT_REG as DT_REG2_15_1_, reg0_.DT_REG_TS as DT_REG_TS3_15_1_, reg0_.DT_UNREG as DT_UNREG4_15_1_, reg0_.DT_UNREG_TS as DT_UNREG_TS5_15_1_, reg0_.LSK as LSK6_15_1_, reg0_.FK_PERS as FK_PERS7_15_1_, reg0_.FK_REG_STATUS as FK_REG_STATUS8_15_1_, reg0_.FK_REG_TP as FK_REG_TP9_15_1_ from PS.REG reg0_ where reg0_.LSK=? 
Reg=1996-03-12 00:00:00.0Check 4 
3382 [main] DEBUG org.hibernate.SQL - select distinct house0_.ID as ID1_1_, house0_.FK_K_LSK as FK_K_LSK2_1_, house0_.FK_STREET as FK_STREET3_1_ from AR.HOUSE house0_ left outer join AR.KW kw1_ on (house0_.ID=kw1_.FK_HOUSE)left outer join AR.KART kart2_ on (kw1_.ID=kart2_.FK_KW)left outer join PS.REG reg3_ on (kart2_.LSK=reg3_.LSK)left outer join PS.REG_STATE regstate4_ on (kart2_.LSK=regstate4_.LSK) where house0_.FK_K_LSK=187804 

時点で私が見る「1を確認してください」:

public void checkAll() { 
    Session sess = (Session) em.getDelegate(); 
    System.out.println("Check 1"); 
    Query query = sess.createQuery("select distinct t from House t left join fetch Kw k on t.id=k.fkHouse " 
      + "left join fetch Kart a on k.id=a.fkKw " 
      + "left join fetch Reg r on a.lsk=r.lsk " 
      + "left join fetch RegState s on a.lsk=s.lsk " 
      + " " 
      + "where t.klsk = 187804"); 
    System.out.println("Check 2"); 
    List<House> lst =query.list(); 
    for (House o : lst) { 
     System.out.println("Check 3"); 
     for (Kw kw : o.getKw()) { 
      for (Kart kart : kw.getLsk()) { 
       for (Reg reg : kart.getReg()) { 
        System.out.print("Reg="+reg.getDtReg());  
        break; 
       } 
       break; 
      } 
      break; 
     } 
     break; 
    } 
    System.out.println("Check 4"); 
} 

を私は次の参照にHibernateのSQLのデバッグをオンにしましたSQLを結合して、それは良いです、 しかし、なぜ "チェック3"私は奇妙なSQLを参照して、再びベースにヒット?

私は、ポイント "Check 1"、 で "left join fetch"、 を使用してすべての子をロードするように強制しましたが、なぜデータベースから子を再度取得する必要があるのですか?

子供のエンティティを取得する方法を変更する必要がありますか教えてください。 私は解決しなければならないHibernate N + 1の問題かもしれませんか?

+0

私は@BatchSizeを追加しようとしました(サイズ= 50)を私の@OneToManyのジョインに変換する...真剣にフェッチの速度を上げますが、別の奇妙なSQLが見えますが、左のジョインは見えません:kart0_.FK_KWをFK_KW4_2_1_、kart0_.LSKをLSK1_2_1_、kart0_.LSKをLSK1_2_0、 kart0_.FK_K_LSKをFK_K_LSK2_2_0_、kart0_.FIOをFIO3_2_0_、k AR0K.kartからのFK_KW4_2_0_としてのart0_.FK_KW kart0_.FK_KW in(?、?、?、?、?、?、?、?、?、?、?、?、 「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜」「〜 – Lev

+0

さらに、私のエンティティをチェックして、間違いを発見しました。 @ shankarsh15のおかげで – Lev

答えて

1

はい、"N+1" selectという問題が発生しています。

N+1 selectの問題を回避するには、House Entityに関連するすべての関連付け、特にOne-One関連付けをフェッチするようにしてください。

また、HQLは、例のような方法で記述する必要があります

は以下を示し 、

SELECT employee FROM Employee employee LEFT JOIN FETCH employee.employer 

下記のHQLのドキュメントを通過してください:

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-from

+0

さらに、私は自分のエンティティをチェックして、間違いを発見しました。 @ shankarsh15のおかげで – Lev

関連する問題