HibernateクエリにOracleのヒントを埋め込む方法

HibernateクエリにOracleヒントを埋め込む方法

Oracleヒントを使用すると、Oracle実行計画を変更して、Oracleがデータベースからデータを取得する方法に影響を与えることができます。 Oracle optimizer hintsの詳細については、こちらをご覧ください。

Hibernateでは、HibernateクエリにOracleヒントを埋め込むことができますか?

Hibernate setComment()?

Hibernateカスタムコメント「setComment()」関数を使用して、OracleヒントをHQLに埋め込むことができますか? ここで例を見てみましょう

1. 元のHibernateクエリ

これは、銘柄コードで銘柄を取得するための単純な選択HQLです。

String hql = "from Stock s where s.stockCode = :stockCode";
List result = session.createQuery(hql)
.setString("stockCode", "7277")
.list();

出力

Hibernate:
    select
        stock0_.STOCK_ID as STOCK1_0_,
        stock0_.STOCK_CODE as STOCK2_0_,
        stock0_.STOCK_NAME as STOCK3_0_
    from example.stock stock0_
    where stock0_.STOCK_CODE=?

2. Hibernate setComment()を試してください

カスタムコメントをログファイルまたはコンソールに出力するには、Hibernateの構成ファイル(hibernate.cfg.xml)でhibernate.use_sql_commentsを有効にします。


...

 
    ...
    true
    true
    true
    
  

HibernatesetComment()を使用して、クエリにカスタムコメントを挿入します。

String hql = "from Stock s where s.stockCode = :stockCode";
List result = session.createQuery(hql)
.setString("stockCode", "7277")
.setComment("+ INDEX(stock idx_stock_code)")
.list();

出力

Hibernate:
    /* + INDEX(stock idx_stock_code) */ select
        stock0_.STOCK_ID as STOCK1_0_,
        stock0_.STOCK_CODE as STOCK2_0_,
        stock0_.STOCK_NAME as STOCK3_0_
    from example.stock stock0_
    where stock0_.STOCK_CODE=?

3. これでいいですか?

そうではありません。Hibernateのカスタムコメントには2つの問題があります。

1. Oracleヒントは、「select」の前ではなく後に追加する必要があります。

Hibernateが生成したクエリ

 /* + INDEX(stock idx_stock_code) */ select

正しい方法は…

select  /*+ INDEX(stock idx_stock_code) */

2. Hibernateは、「/ * +」の間に余分なスペースを自動的に追加します。

Hibernateには、OracleヒントをHibernateクエリ言語(HQL)に埋め込む公式の方法はまだありません。

P.S Thanks Pete contribute on this.

実用的なソリューション

唯一の解決策は、HibernatecreateSQLQueryメソッドを使用してネイティブSQLステートメントを実行することです。

String hql = "/*+ INDEX(stock idx_stock_code) */
    select * from stock s where s.stock_code = :stockCode";
List result = session.createQuery(hql)
.setString("stockCode", "7277")
.list();

出力

Hibernate:
    /*+ INDEX(stock idx_stock_code) */ select *
    from stock s where s.stock_code = ?

More(t0)s。