すべての基準クエリで機能する別の一般的なソリューションがあります。
標準のコメントと Hibernate Interceptor を使用して、最終的な SQL をデータベースに変更します。
(私は Hibernate 3.3 で使用しましたが、すべてのバージョンで使用できるはずです。Interceptor の登録は異なる場合があります。)
クエリ コードで次を使用します。
criteria.setComment("$HINT$ push_pred(viewAlias)");
SQL テキストに変更するインターセプターを作成します (これは commons.lang3.StringUtils を使用します)。
public class HibernateEntityInterceptor extends EmptyInterceptor {
@Override
public String onPrepareStatement(String sql) {
if (sql.startsWith("/* $HINT$")) {
String hintText = StringUtils.substringBetween(sql, "/* $HINT$", "*/");
sql = sql.replaceFirst("select ", "select /*+" + hintText + "*/ ");
}
return sql;
}
上記は Oracle 用ですが、すべての DBMS で簡単に調整できるはずです。
ヒント マーカー「$HINT$」の定数を作成できる/作成する必要があるかもしれません。
ロギングも行う必要があります (Interceptor の正しい呼び出しを簡単に確認できるようにするため)。簡単にするために、上記では省略しました。
Interceptor を登録する必要があります。春には、これはで行われapplicationContext.xml
ます:
<bean id="entityListener" class="your.package.HibernateEntityInterceptor"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="entityInterceptor" ref="entityListener"/>
[...]
または (Hibernate 3.3 ドキュメントからコピー):
Session スコープのインターセプターは、Interceptor を受け入れるオーバーロードされた SessionFactory.openSession() メソッドの 1 つを使用してセッションが開かれるときに指定されます。
Session session = sf.openSession( new HibernateEntityInterceptor() );
SessionFactory スコープのインターセプターは、SessionFactory を構築する前に Configuration オブジェクトに登録されます。使用するインターセプターを明示的に指定してセッションが開かれない限り、提供されたインターセプターは、その SessionFactory から開かれたすべてのセッションに適用されます。SessionFactory スコープのインターセプターは、スレッドセーフである必要があります。複数のセッションがこのインターセプターを同時に使用する可能性があるため、セッション固有の状態を保存しないようにしてください。
new Configuration().setInterceptor( new HibernateEntityInterceptor() );