Hibernate 4 et les fonctions d'agrégat

Comment réaliser des requêtes avec de telles fonctions dans la clause SELECT en Hibernate 4 ? C'est ce que nous vous proposons de voir dans cet article.

Florent TRIPIER
Mis à jour le 7 Mai 2025

En SQL, les fonctions d’agrégat sont les fonctions COUNT(), SUM(), MIN(), MAX() et AVG(). Comment réaliser des requêtes avec de telles fonctions dans la clause SELECT en Hibernate 4 ?

Théorie

Si vous n’êtes pas familier avec Hibernate 4, reportez-vous préalablement à l’article  ».

Les fonctions d’agrégats sont fournies par le CriteriaBuilder. Il suffit donc de passer en paramètre à votre fonction select() non pas un champ ou un Root mais la fonction d’agrégat. Vous passez en paramètre à celles-ci les champs concernés.

Exemple

Si je veux compter les commandes :

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<
Long> criteriaQuery = builder.createQuery(Long.class);
Root<
Commande> root = criteriaQuery.from(Commande.class);
criteriaQuery.select(builder.count(root));
TypedQuery<
Long> typedQuery = entityManager.createQuery(criteriaQuery);
Long result = typedQuery.getSingleResult();

ou si je cherche le montant le plus élevé :

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<
Double> criteriaQuery = builder.createQuery(Double.class);
Root<
Commande> root = criteriaQuery.from(Commande.class);
criteriaQuery.select(builder.max(root.get(Commande_.total)));
TypedQuery<
Double> typedQuery = entityManager.createQuery(criteriaQuery);
List<
Double> result = typedQuery.getResultList();

ou encore si je veux connaître le panier moyen :

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<
Double> criteriaQuery = builder.createQuery(Double.class);
Root<
Commande> root = criteriaQuery.from(Commande.class);
criteriaQuery.select(builder.avg(root.get(Commande_.total)));
TypedQuery<
Double> typedQuery = entityManager.createQuery(criteriaQuery);
List<
Double> result = typedQuery.getResultList();

Attention ! N’oubliez pas de modifier le type de votre CriteriaQuery et de votre TypedQuery en fonction de ce que vous voulez ramener. 

Remarque : si votre clause SELECT contient un COUNT() et rien d’autre, et seulement dans ce cas là, vous pouvez appeler la fonction getSingleResult() à la place de getResultList(). Pourquoi pas le reste du temps ? Parce que getSingleResult() propage une exception lorsque la requête ramène un nombre de résultat différent de 1 (zéro compris). Or COUNT() ramène forcément un résultat puisque s’il ne trouve rien il renvoie 0, alors que SUM() par exemple est susceptible de retourner NULL.