2011-11-15 6 views
32

Avant de poster cette question, j'ai déjà regardé this, mais je n'ai pas pu obtenir ce que je cherchais.javax.persistence.NoResultException: Aucune entité trouvée pour la requête

Je sais que pour la requête que j'ai écrite, il peut exister seulement une ligne ou pas du tout. Donc, il n'y a pas de raison pour moi d'utiliser getResultList().

Voici mon code:

String hql="from DrawUnusedBalance where unusedBalanceDate= :today"; 
Query query=em.createQuery(hql); 
query.setParameter("today",new LocalDate()); 

DrawUnusedBalance drawUnusedBalance= 
    (DrawUnusedBalance)query.getSingleResult();// we can have only a 
               // single datum per day 
//`System.out.println(drawUnusedBalance.toString());` 

Le problème est, s'il n'y a pas de ligne, il jette une exception, et sinon il fonctionne très bien. Je connais le problème mais je cherche aussi la meilleure solution. Ce que je voulais, c'est que s'il n'y avait pas de ligne dans la DB je voulais obtenir un objet nul (au lieu d'avoir une exception) donc j'insérerais une nouvelle donnée, si elle n'est pas nulle, je veux juste mettre à jour il.

Il y a une façon de gérer cela, ce qui, je crois, n'est pas la bonne façon de le faire. C'est: Je vais avoir un bloc try-catch et s'il lance une exception, je peux écrire pour insérer de nouvelles données dans le DB sur le bloc catch. Mais je crois qu'il y aura un meilleur moyen.

Répondre

60

Oui. Vous devez utiliser le bloc try/catch, mais pas besoin d'attraper le Exception. Selon le API il lancera NoResultException s'il n'y a pas de résultat, et c'est à vous de décider comment vous voulez le gérer.

DrawUnusedBalance drawUnusedBalance = null; 
try{ 
drawUnusedBalance = (DrawUnusedBalance)query.getSingleResult() 
catch (NoResultException nre){ 
//Ignore this because as per your logic this is ok! 
} 

if(drawUnusedBalance == null){ 
//Do your logic.. 
} 
+0

Merci ManuPK ... Mais je dois encore écrire du code qui crée un objet et persiste faire un DB .. dans le Catch bloc .... et je pensais que ce ne serait pas un bon moyen de conserver les données d'un bloc catch ... Bien que tnx pour votre réponse. – WowBow

+1

Je pense qu'il n'y a rien de mal à attraper une ** exception vérifiée ** et à prendre un chemin alternatif. C'est pourquoi l'APP vous donne l'option sur la façon dont vous voulez le gérer. En fait, la méthode que vous recherchez est disponible dans [hibernate] (http://docs.jboss.org/hibernate/core/3.2/api/org/hibernate/Query.html#uniqueResult()) qui n'est pas disponible avec JPA . – ManuPK

+0

@ user1017111 J'ai eu votre problème en écrivant du code dans le ** catch **. J'ai légèrement mis à jour la réponse pour rendre le code lisible. – ManuPK

6

Vous avez mentionné obtenir la liste des résultats de la requête, puisque vous ne savez pas qu'il ya un uniqueResult (donc l'exception), vous pouvez utiliser la liste et vérifier la taille?

if (query.list().size() == 1) 

Puisque vous ne faites pas un get() pour obtenir votre unique objet d'une requête sera exécutée si vous appelez uniqueResult ou liste.

+0

Pour l'instant, j'utilise le query.list(). IsEmpty() pour voir s'il y a des données retournées ... Je pensais que ce serait facile pour le programmeur si nous obtenions un objet nul comme la méthode get() . Merci – WowBow

+0

Pas de problème. IsEmpty était évidemment ce que je voulais dire quand j'ai écrit ma réponse;) –

+0

..J'ai eu ça. Parfois, il est bon d'avoir un moyen alternatif – WowBow

2

Lorsque vous ne savez pas s'il y a des résultats, utilisez getResultList().

List<User> foundUsers = (List<User>) query.getResultList(); 
     if (foundUsers == null || foundUsers.isEmpty()) { 
      return false; 
     } 
User foundUser = foundUsers.get(0); 
+0

Veuillez expliquer comment le code répond à la question. – jxh

+0

OK, c'est une suggestion plutôt qu'une réponse. Mais pourrait être utile aux autres. – ACV

+0

Lorsque vous ne savez pas s'il y a des résultats, utilisez getResultList(). 'Liste foundUsers = (Liste ) query.getResultList(); if (foundUsers == null || foundUsers.isEmpty()) { return false; } Utilisateur trouvéUser = foundUsers.get (0); ' – ACV

5

Lorsque vous utilisez java 8, vous pouvez profiter de l'API de flux et simplifier le code à

return (YourEntityClass) entityManager.createQuery() 
.... 
.getResultList() 
.stream().findFirst(); 

Cela vous donnera java.util.Optional

Si vous préférez null au lieu, tout vous avez besoin est

... 
.getResultList() 
.stream().findFirst().orElse(null); 
Questions connexes