Hibernate Computerizzata Criterio di ordinazione
Domanda
Ho una colonna di Oracle XMLType che memorizza le varie stringhe in lingua originale. Ho bisogno di costruire un criterio di Hibernate che gli ordini su questa colonna. Per fare questo, ho bisogno di estrarre il valore di una funzione di Oracle. Questo criterio viene generato automaticamente dal codice che ho scritto, ma non posso, per la vita di me, a capire come estrarre il valore e l'ordine su di esso tramite l'API criteri. In sostanza, l'SQL generato dovrebbe essere simile a:
SELECT EXTRACTVALUE(title, '//value[@lang="EN"]') AS enTitle
FROM domain_object
ORDER BY enTitle
I giocherellava con proiezioni momentaneamente, ma sembrano eseguire una seconda select. Che presumo causerebbe ibernazione per selezionare tutti i valori e in memoria sorta di loro basati sulla proiezione? Questo sarebbe molto auspicabile = \
Soluzione
Ok, ho trovato a soluzione. Non che questo sia il migliore , quindi mi lasciarla aperta per un po ', se qualcuno vuole fornire una risposta migliore / perfezionare la mia soluzione.
Quello che ho fatto è stato di estendere org.hibernate.criterion.Order
nel seguente modo:
package com.mycorp.common.hibernate;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Order;
import org.hibernate.engine.SessionFactoryImplementor;
import com.mycorp.LocalizationUtil;
public class LocalStringOrder extends Order {
private static final long serialVersionUID = 1L;
private boolean ascending;
private String propName;
public LocalStringOrder(String prop, boolean asc) {
super(prop, asc);
ascending = asc;
propName = prop;
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propName);
StringBuffer fragment = new StringBuffer();
for ( int i=0; i<columns.length; i++ ) {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
fragment.append( factory.getDialect().getLowercaseFunction() )
.append('(');
fragment.append("EXTRACTVALUE(");
fragment.append( columns[i] );
fragment.append(", '//value[@lang=\"" +
LocalizationUtil.getPreferedLanguage().name() +
"\"')");
fragment.append(')');
fragment.append( ascending ? " asc" : " desc" );
if ( i<columns.length-1 ) fragment.append(", ");
}
return fragment.toString();
}
public static Order asc(String propertyName) {
return new LocalStringOrder(propertyName, true);
}
public static Order desc(String propertyName) {
return new LocalStringOrder(propertyName, false);
}
}
Allora era solo una questione di dire criteria.addOrder(LocalStringOrder.asc('prop'))
.
Altri suggerimenti
Un'altra soluzione generale è NativeSQLOrder, vedi http: //opensource.atlassian. com / progetti / hibernate / browse / HHH-2381 . Non undestand, perché questa funzione non è in Hibernate ancora.