2009-09-02 6 views
2

j'ai une requête qui renvoie une liste d'objets comme par exemple:une colonne dans hql clause select sans réellement utiliser cette colonne

select distinct ref from references where [...] 

Je voudrais commander ces par un champ non sur ref mais une association de référence, à savoir:

select distinct ref from references where [...] order by ref.foo.name 

Malheureusement, cela ne fonctionne pas dans Oracle (une fois que la requête est traduite en SQL) car il ne peut effectuer un tri sur cette colonne si elle est incluse dans la sélection. Y a-t-il un moyen de renvoyer la colonne, sans que Hibernate ne la prenne en charge? Je voudrais juste retourner une liste au lieu de devoir balayer avec les tableaux Object [] qu'elle renverrait autrement.

Répondre

0

Il est parfaitement possible pour Oracle de trier une requête par une colonne qui ne figure pas dans la sélection:

SQL> select ename from emp 
    2 order by empno 
    3/

ENAME 
---------- 
CLARKE 
VAN WIJK 
PADFIELD 
ROBERTSON 
BILLINGTON 
SPENCER 
BOEHMER 
RIGBY 
SCHNEIDER 
CAVE 
KULASH 
HALL 
GASPAROTTO 
KISHORE 

14 rows selected. 

SQL>

Mais votre clause ORDER BY ressemble un peu particulière - order by ref.foo.name - Peut-être qu'il me manque un peu de subtilité?

Modifier Vincent a souligné la subtilité que je manquais - l'utilisation de DISTINCT.

SQL> select distinct ename from emp 
    2 order by empno 
    3/
order by empno 
     * 
ERROR at line 2: 
ORA-01791: not a SELECTed expression 


SQL> 

La nécessité d'utiliser DISTINCT est souvent révélatrice d'un défaut de conception, soit un élément manquant dans la clause WHERE ou un modèle de données insuffisamment normalisé. Bien que cela n'aide pas le questionneur qui a probablement juste besoin d'une solution de contournement.

+0

Dans le cas d'OP, cela n'est pas possible à cause du DISTINCT. Lorsque vous utilisez DISTINCT, cela n'a pas vraiment de sens de commander par quelque chose qui ne figure pas dans la liste SELECT. –

+0

Je suppose que je n'étais pas très clair. La requête est en HQL. Il y a beaucoup d'une association de ref à foo de sorte qu'il y aura un ref.foo.name pour chaque ref. En langage SQL, je pouvais simplement écrire moi-même la jointure et ajouter le champ au select, mais j'espérais ne pas avoir à réécrire la requête. – wds

0

Du côté de Hibernate, une solution simple serait que votre code DAO s'occupe de votre problème. Votre demande ajouterait la colonne.

Votre méthode Dao recevrait de Hibernate une liste, et la traduirait.

List<Object[]> rawResults = query....; 
List<References> results = new ArrayList<References>(rawResults.size()); 
for(Object[] rawResult : rawResults) { 
    results.add(rawResults[0]); 
} 
return results; 
0

Sur Oracle lorsque vous utilisez une fonction « d'agrégation » (distincte, groupe par, compter, ...) pour trier les résultats que vous devez inclure champ dé votre choix dans la clause select, parce que la « distincte 'clause fonctionne comme un' groupe par ', ce que fait Hibernate est de sélectionner toutes les colonnes de votre objet avec une agrégation' distincte '. Peut-être que vous devriez essayer d'utiliser la fonction 'group by' dans HQL de cette façon, hibernate peut traduire dans la forme correcte votre jointure dans le groupe par fonction.

Questions connexes