Domanda

Esiste un modo per creare una query Distinct in HQL. O usando il "distinto" parola chiave o qualche altro metodo. Non sono sicuro che distinguere sia un keywork valido per HQL, ma sto cercando l'equivalente HQL della parola chiave SQL "distinto".

È stato utile?

Soluzione

Ecco uno snippet di hql che usiamo. (I nomi sono stati cambiati per proteggere le identità)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});

Altri suggerimenti

Vale la pena notare che la parola chiave distinta in HQL non si associa direttamente alla parola chiave distinta in SQL.

Se usi la parola chiave distinta in HQL, a volte Hibernate utilizzerà la parola chiave SQL distinta , ma in alcune situazioni utilizzerà un trasformatore di risultati per produrre risultati distinti . Ad esempio, quando si utilizza un join esterno come questo:

select distinct o from Order o left join fetch o.lineItems

In questo caso non è possibile filtrare i duplicati a livello di SQL, quindi Hibernate utilizza un ResultTransformer per filtrare i duplicati dopo la query SQL è stata eseguita.

fai qualcosa del genere la prossima volta

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();

Puoi anche utilizzare Criteria.DISTINCT_ROOT_ENTITY anche con la query Hibernate HQL.

Esempio:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();

Ho avuto dei problemi con i trasformatori di risultati combinati con le query HQL. Quando ho provato

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

non ha funzionato. Ho dovuto trasformare manualmente in questo modo:

final List found = trans.transformList(qry.list());

Con i trasformatori API Criteria ha funzionato perfettamente.

La mia query principale sembrava così nel modello:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

E non riuscivo ancora a ottenere ciò che consideravo "distinto". risultati. Erano semplicemente distinti in base a una combinazione di chiavi primarie nella tabella.

Quindi nel DaoImpl ho aggiunto un cambio di una riga e ho finito per ottenere il "distinto" ritorno volevo. Un esempio sarebbe invece di vedere 00 quattro volte che ora lo vedo solo una volta. Ecco il codice che ho aggiunto al DaoImpl :

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

Spero che questo abbia aiutato! Ancora una volta, questo potrebbe funzionare solo se stai seguendo le pratiche di codifica che implementano il servizio, il dao e il tipo di modello del progetto.

Supponi di avere un'entità cliente mappata sulla tabella CUSTOMER_INFORMATION e desideri ottenere un elenco di nomi distinti di nome cliente. Puoi utilizzare lo snippet di seguito per ottenere lo stesso.

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

Spero che sia d'aiuto. Quindi qui stiamo usando il gruppo invece di usare una parola chiave distinta.

Inoltre in precedenza ho trovato difficile usare una parola chiave distinta quando volevo applicarla a più colonne. Ad esempio, voglio ottenere un elenco di distinti firstName, lastName quindi group by semplicemente funzionerebbe. Ho avuto difficoltà a usare distinti in questo caso.

Puoi essere la parola chiave distinta nel tuo costruttore di criteri in questo modo.

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

E crea il costruttore di campi nella tua classe di modello.

Ho una risposta per Hibernate Query Language per usare i campi Distinct. Puoi utilizzare * SELECT DISTINCT (TO_CITY) DA FLIGHT_ROUTE *. Se si utilizza la query SQL , viene restituito Elenco stringhe. Non è possibile utilizzare il valore restituito dalla Classe di entità. Quindi la risposta per risolvere quel tipo di problema è usare HQL con SQL .

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

Dall'istruzione di query SQL ha ottenuto DISTINCT ROUTE_ID e inserito come Elenco. E la query IN filtra il TO_CITY distinto da IN (Elenco).

Il tipo restituito è di tipo Entity Bean. Quindi puoi farlo in AJAX come Complemento automatico .

Potrebbe essere tutto OK

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