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 = \

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top