У меня есть другое общее решение, которое должно работать для каждого запроса Criteria:
используйте стандартный комментарий и перехватчик Hibernate, изменяющий окончательный SQL в базе данных.
(Я использовал его с Hibernate 3.3, но должен быть применим для каждой версии, регистрация перехватчика может быть разной.)
В вашем коде запроса используйте:
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, но должно легко настраиваться для каждой СУБД.
Возможно, вы можете / должны создать константу для маркера подсказки "$ HINT $".
Ведение журнала также должно быть сделано (чтобы вы могли легко увидеть правильный вызов Перехватчика), я упустил это выше для простоты.
Перехватчик должен быть зарегистрирован. Весной это делается в 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):
Перехватчик в области сеанса указывается при открытии сеанса
используя один из перегруженных методов SessionFactory.openSession ()
принимает перехватчик.
Session session = sf.openSession( new HibernateEntityInterceptor() );
Перехватчик SessionFactory-scoped зарегистрирован с
Объект конфигурации до создания SessionFactory. Если только
сеанс открывается в явном виде с указанием перехватчика для использования,
поставляемый перехватчик будет применяться ко всем сеансам, открытым с этого
SessionFactory. Перехватчики ScopeFactory-scoped должны быть потоковыми
безопасный. Убедитесь, что вы не сохраняете состояния сеанса, так как
несколько сеансов будут использовать этот перехватчик потенциально одновременно.
new Configuration().setInterceptor( new HibernateEntityInterceptor() );