Javax.persistence.Query.getResultList () peut-il retourner null?

115

Et si oui, dans quelles circonstances?

Les spécifications Javadoc et JPA ne disent rien.

rdk
la source
Je cherchais exactement cette question! tks! jusqu'à 4 vous!
rafa.ferreira

Réponses:

69

Vous avez raison. La spécification JPA n'en dit rien. Mais le livre Java Persistence with Hibernate, 2e édition , dit:

Si le résultat de la requête est vide, un null est renvoyé

L'implémentation Hibernate JPA (Entity Manager) renvoie null lorsque vous appelez query.getResultList () sans résultat.

METTRE À JOUR

Comme l'ont souligné certains utilisateurs, il semble qu'une dernière version d'Hibernate renvoie une liste vide à la place.

Une liste vide est également renvoyée dans Eclipselink lorsqu'aucun résultat n'est trouvé.

Arthur Ronald
la source
29
C'est certainement obsolète, Hibernate renvoie une liste vide.
Michael Laffargue
2
Je reçois toujours null de Hibernate 4.3.10 (fonctionnant en tant que moteur JPA pour Spring Data). Cela ne se produit que pour une seule requête native, car les requêtes JPA classiques fonctionnent comme prévu.
Jacek Prucia
1
Vérifiez simplement les deux conditions en utilisant OU. if(rows == null || rows.size == 0){}où les lignes est ce que la getResultList () renvoie
Number945
Enveloppez-le simplement dans un Optional.ofNullable () et vous êtes prêt.
de.la.ru
Je pense que le retour nullau lieu d'une liste vide n'est pas ce que la spécification vise, car cela indique assez clairement quand il faut s'attendre nullà d'autres endroits. Surtout que la documentation pour les getResultListlectures Execute a SELECT query and return the query results as a(n) (un)typed List. - @return a list of the results. Je vérifierais toujours nullbien sûr et retournerais moi-même une liste vide si nécessaire.
René
23

Si les spécifications disaient que cela ne pouvait pas arriver, les croiriez-vous? Étant donné que votre code pourrait éventuellement fonctionner avec différentes implémentations JPA, feriez-vous confiance à chaque implémenteur pour bien faire les choses?

Quoi qu'il en soit, je coderais de manière défensive et vérifierais null.

Maintenant, la grande question: devons-nous également traiter "null" et une liste vide? C'est là que les spécifications devraient nous aider, et non.

Je suppose qu'un retour nul (si effectivement cela pouvait arriver) serait équivalent à "Je n'ai pas compris la requête" et une liste vide serait "Oui, j'ai compris la requête, mais il n'y avait pas d'enregistrements".

Vous avez peut-être un chemin de code (probablement une exception) qui traite des requêtes non analysables, j'aurais tendance à diriger un retour nul sur ce chemin.

djna
la source
+1 vous avez tellement raison de dire: "Feriez-vous confiance à tous les fournisseurs JPA?" NO :)
dfa
Modifié pour ajouter: Arthur a souligné que JPA d'Hibernate renvoie en fait null si aucun enregistrement n'est trouvé. Donc, en fait, dans ce cas, nous devons replier la liste nulle et la liste vide. Je crois que le processus de réflexion que nous avons traversé ci-dessus est toujours valable. Il est même concevable que nous ayons différents traitements de null pour différentes piles JPA. Bienvenue dans le plaisir de la portabilité.
djna le
D'accord. Il n'existe que du «plaisir de portabilité» en raison du fait que la spécification JPA ne fait pas ce qu'elle devrait faire ... spécifiez la sémantique précise. Dommage qu'il soit dirigé par un comité avec des intérêts particuliers.
DataNucleus
2
"Je n'ai pas compris la requête" doit être traité comme Exception, renvoyer nullCollectionest dans le type de retour est un défaut de conception évident
matoni
13

Contrairement à l'article d'Arthur, lorsque j'ai exécuté une requête à laquelle aucune entité ne correspondait, j'ai obtenu une liste vide, non nulle. Cela utilise Hibernate et c'est ce que je considère comme un comportement correct: une liste vide est la bonne réponse lorsque vous demandez une collection d'entités et qu'il n'y en a pas.

Andrew Simons
la source
2
pour OpenJPA, j'obtiens également une liste vide au lieu de null.
Gnavvy
3

Si vous regardez de plus près le org.hibernate.loader.Loader(4.1), vous verrez que la liste est toujours initialisée dans la méthode processResultSet () ( doc , source ).

protected List processResultSet(...) throws SQLException {
   final List results = new ArrayList();

   handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session );
   ...
   return results;

}

Donc je ne pense pas qu'il retournera null maintenant.

Charles Follet
la source
2
Vive l'extrait de code exact. Mais cette réponse se concentre uniquement sur la mise en veille prolongée, qui est l'une des implémentations de la spécification. D'autres implémentations comme OpenJPA diffèrent par le comportement. En outre, la mise en veille prolongée semble avoir changé le comportement sur différentes versions.
venky
1

Bien sûr, si vous testez l'ensemble de résultats avec CollectionUtils.isNotEmpty de Jakarta, vous êtes couvert de toute façon.

Al Scherer
la source
0

Query.getResultList()renvoie une liste vide au lieu de null. Vérifiez donc isEmpty()le résultat renvoyé et continuez avec le reste de la logique s'il est faux.

Cyril Sojan
la source
0

Compte tenu de l'implémentation de getResultsList()in org.hibernate.ejb.QueryImplclass, il est possible de retourner un null:

public List getResultList() {
    try {
        return query.list();
    }
    catch (QueryExecutionRequestException he) {
        throw new IllegalStateException(he);
    }
    catch( TypeMismatchException e ) {
        throw new IllegalArgumentException(e);
    }
    catch (HibernateException he) {
        em.throwPersistenceException( he );
        return null;
    }

Ma version d'hibernation est: 3.3.1.GA

wile le coyote
la source