Cet article est plus un pense-bête qu’autre chose, mais ayant passé beaucoup de temps à chercher sur le net et ayant finalement trouvé la solution à mon problème, j’ai décidé de la faire partager à tout le monde.
Mon problème étant à l’origine une incapacité à appliquer un tri sur un champ de type VARCHAR contenant des nombres, j’obtenais un classement selon leur longueur (1, 10, 100, 2, 20,…) au lieu d’un classement par ordre décimale (1, 2, 10, 20, 100,…).
HQL : Langage de requêtage d’Hibernate
Hibernate fourni un langage d’interrogation extrêmement puissant qui ressemble au SQL. Il se distingue par sa syntaxe qui se veut totalement orienté object, comprenant des notions d’héritage, de polymorphisme et d’association.

© http://simoes.org
Une panoplie d’expressions sont autorisés dans la clause WHERE, allant des opérateurs logiques (and, or, not …) aux fonctions définies par EJB-QL 3.0 (trim(), lower(), substring() ,mod() …) en passant par n’importe quelle fonction supportée par la base de données (sign(), trunc(), rtrim() …).
Dans cette panoplie d’expressions permises on y trouve celle qui nous importe pour cet article : cast(… , …), où le second argument est le nom d’un type Hibernate. Cette méthode permet la conversion de type de données (ou transtypage) en modifiant le type d’une donnée en une autre.
Voici un exemple de requête HQL utilisant le cast :
Query query = getSession().createQuery("from Card c where cast(c.power, int) > :power");
query.setParameter("power", 11, Hibernate.INTEGER);
return query.list();
Criteria API : Requêtes par critères
Hibernate offre aussi une API d’interrogation par critères intuitive, extensible, puissante et élégante qui permet de réaliser autant que l’utilisation du langage HQL. Elle est surtout adaptée pour l’écriture dynamique de recherche multi-critères où les requêtes doivent être construites à la volée.
Les développeurs ont tendance à préférer son utilisation par rapport à HQL car il y a généralement beaucoup moins de lignes de code à saisir, le code en ressort plus propre et facile à maintenir.

© http://techiedan.com
Malheureusement aucune fonction native permet d’appliquer une conversion de type de données, il faut pour cela appeler la fonction SQL de ‘cast’ de votre base de données depuis la requête Criteria.
Voici la façon de spécifier directement du SQL en reprenant l’exemple du premier paragraphe :
Criteria criteria = getSession().createCriteria(Card.class);
criteria.add(Restrictions.sqlRestriction("cast({alias}.power as signed integer) > ?", 11, Hibernate.INTEGER));
return criteria.list();
La zone {alias} sera remplacée par l’alias de colonne de l’entité que l’on souhaite interroger.
L’exemple fournit communique avec une base de données relationnelle de type MySQL5 (d’où le ‘signed integer’).




Affichez votre portrait
{ 2 commentaires… à vous de vous exprimer ! }
Ding 50ème article dans la rubrique « programmation »
Cinquantième… tu m’avais caché que tu possédais aussi un côté « Lettres » enfoui en toi