ho un'altra soluzione generica, che dovrebbe funzionare per ogni query Criteri:
utilizzare un commento standard ed un Hibernate Interceptor cambiare lo SQL finale al database.
(L'ho usato con Hibernate 3.3, ma dovrebbe essere utilizzabile per ogni versione, la registrazione dell'Interceptor potrebbe essere diversa.)
Nell'interrogazione utilizzare il codice:
criteria.setComment("$HINT$ push_pred(viewAlias)");
Scrivi un intercettore per passare al testo SQL (questo usa 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;
}
Sopra è per Oracle, ma dovrebbe essere facilmente regolabile per ogni DBMS.
Forse è possibile/dovrebbe creare una costante per l'indicatore di suggerimento "$ HINT $".
Anche la registrazione deve essere eseguita (in modo da poter vedere facilmente la chiamata corretta dell'intercettore), l'ho lasciata fuori per semplicità.
L'intercettore deve essere registrato. In primavera questo è fatto in applicationContext.xml
:
<bean id="entityListener" class="your.package.HibernateEntityInterceptor"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="entityInterceptor" ref="entityListener"/>
[...]
Or (copia dai Hibernate 3.3 docs): intercettore
Una sessione con ambito viene specificato quando si apre una sessione utilizzando uno dei SessionFactory sovraccarico metodi .openSession() accettando un intercettore.
Session session = sf.openSession(new HibernateEntityInterceptor());
A intercettore SessionFactory con ambito è registrata con l'oggetto configurazione prima di costruire la SessionFactory. A meno che non venga aperta una sessione che specifica l'intercettore da utilizzare, l'intercettore fornito da verrà applicato a tutte le sessioni aperte da tale SessionFactory . Gli intercettori con scope SessionFactory devono essere protetti da thread . Assicurarsi di non archiviare stati specifici della sessione, dal momento che più sessioni useranno questo intercettatore potenzialmente simultaneamente da .
new Configuration().setInterceptor(new HibernateEntityInterceptor());
il risultato sarà davvero essere user-faccia. –
la query stessa è corretta così com'è. poiché è generato dinamicamente, non può essere ottimizzato manualmente, è diverso per ogni query di ricerca. –