Hibernate utilisé avec la base de données PostgreSQL lors de la commande de desc par une colonne met les valeurs nulles supérieures à celles non nulles.
La norme SQL99 propose le mot-clé "NULLS LAST" pour déclarer que les valeurs nulles doivent être placées plus bas que non nulles.
Le comportement "NULLS LAST" peut-il être obtenu à l'aide de l'API Criteria d'Hibernate?
Cette fonctionnalité a été implémentée pendant les versions Hibernate 4.2.x et 4.3.x, comme mentionné précédemment.
Il peut être utilisé comme par exemple:
Criteria criteria = ...;
criteria.addOrder( Order.desc( "name" ).nulls(NullPrecedence.FIRST) );
Les javadocs Hibernate v4.3 sont moins omissifs ici .
Vous pouvez configurer "nulls first"/"nulls last" dans les propriétés de mise en veille prolongée afin qu'il soit capté par tout appel de critère par défaut: hibernate.order_by.default_null_ordering=last
(ou =first
).
Voir ce commit d'hibernation pour plus de détails.
Une autre variante, si vous créez SQL à la volée et n'utilisez pas l'API Criteria:
ORDER BY COALESCE (, '0') [ASC | DESC]
Cela fonctionne pour varchar ou pour les colonnes numériques.
Voici ma mise à jour de la classe par (Pascal Thivent):
for (int i = 0; i < orderByNames.length; i++) {
if (orderByNames[i].trim().length() > 0) {
String orderName = orderByNames[i].trim().toLowerCase();
if (orderName.contains("desc")) {
orderByNames[i] = orderName.replace("desc", "desc NULLS LAST");
} else {
orderByNames[i] = orderName.replace("asc", "asc NULLS FIRST");
}
}
}
Cela résout le problème:
Cela casse si sql a une limite/décalage après la commande par - Sathish 1er avril 11 à 14:52
Voici également comment vous pouvez l'utiliser dans JPA (mise en veille prolongée):
Session session = entityManager.unwrap(Session.class);
Session nullsSortingProperlySession = null;
try {
// perform a query guaranteeing that nulls will sort last
nullsSortingProperlySession = session.getSessionFactory().withOptions()
.interceptor(new GuaranteeNullsFirstInterceptor())
.openSession();
} finally {
// release the session, or the db connections will spiral
try {
if (nullsSortingProperlySession != null) {
nullsSortingProperlySession.close();
}
} catch (Exception e) {
logger.error("Error closing session", e);
}
}
J'ai testé cela sur postgres et cela corrige le problème `` les valeurs nulles sont plus élevées que les non-nulles '' que nous avions.