Hibernate HQLクエリ - JOINによる結合

2008/09/12 21:21Update
TAGS: Hibernate | HQLクエリ | JOIN | 結合 | N+1問題

ネイティブSQLでは、LEFT/RIGHT OUTER JOINなどの結合方法があります。Hibernate HQLクエリはネイティブSQLと同じように、関連性のある永続オブジェクトの間に、JOINによる結合を行うことができます。

Hibernate HQL JOIN


Hibernate HQL がサポートする結合方法は、次の通りです。
◇INNER JOIN もしくはJOIN。両者は同じ意味になります。
◇LEFT JOIN もしくは LEFT OUTER JOIN。
◇RIGHT JOIN もしくは RIGHT OUTER JOIN。

これはSQLと同じです。

使用例
select f from Father f left outer join f.sonSet


注意していただきたいことが、ここでSQLのような ON 句を指定する必要がありません。なぜかというと、その関連情報は既にマッピング情報で指定されているからです。
上の例の場合、
Father.hbm.xmlに
        <set name="sonSet" >
             <key column="FATHER_ID"/>
             <one-to-many class="eg.Son"/>
        </set>
      
  
ようなマッピング情報が定義されています。

即ち、Hibernate HQLでは、関連性のない永続オブジェクト間でJOINによる結合はできません。

HQL JOINサンプル


さて、早速サンプルから見てみましょう。
◇Father.hbm.xml(抜粋)
        <set name="sonSet" cascade="all" inverse="true">
             <cache usage="read-write"/>
             
             <key column="FATHER_ID"/>
             <one-to-many class="eg.Son"/>
        </set>
        


◇テストコード(抜粋)
    public static void testHqlJoin(Session sess) {
        String hql = "select distinct f from Father f left outer join f.sonSet where f.name like 'f%'";
        
        Query query = sess.createQuery(hql);
        List <Father> fatherList = query.list();
        ...
    }
    


◇実行ログ
Hibernate: select distinct father0_.ID as ID, father0_.NAME as NAME0_ from FATHER father0_ left outer join SON sonset1_ on father0_.ID=sonset1_.FATHER_ID where father0_.NAME like 'f%'

また、LAZYロード+JOINの場合、N+1問題を起きてしまい、パフォーマンス低下に招く恐れがあります。N+1問題を回避するには、次の記事も併せてご覧になってください。

Hibernate HQLクエリ join fetch でパフォーマンス改善 | fetch 戦略

その他


上も述べたのように、Hibernate HQLでは、関連性のない永続オブジェクト間でJOINによる結合はできません。
しかし、関連性のない永続オブジェクト間の結合を利用したい場合もあります。その場合、次の方法をお考えください。

◇方法1:
WHERE句に条件式を指定します。
例:
select a, b from EntityA, EntityB where a.id=b.aId
しかし、この方法だと、LEFT JOINのような機能を実装できません。

◇方法2:
ネイティブSQLを使ってJOINを行います。
例:
select a.ID, a.NAME from TABLE_A a left join TABLE_B b on a.ID = b.A_ID

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments