web-dev-qa-db-fra.com

javax.persistence.NoResultException: getSingleResult () n'a pas récupéré d'entité

j'ai créé un namedquery avec ejb pour vérifier si le nom d'utilisateur est utilisé. Lorsque singleResult est null, j'obtiens l'exception suivante:

javax.persistence.NoResultException: getSingleResult() did not retrieve any entities

Mais cette exception est le résultat que je veux quand le nom d'utilisateur est libre. 

Voici le code:

 public User getUserByUsername(String username) throws DAOException{
    try{
        Query q = em.createNamedQuery(User.getUserByUsername);
        q.setParameter("username", username);
        return (User) q.getSingleResult();
    }catch(Exception e){
        throwException(username, e);
        return null;
    }
}

Quelqu'un sait-il quel est le problème? :(

Je voudrais retourner null et ne pas obtenir une exception.

Merci beaucoup

15
apple1988

Vous semblez renvoyer l'exception dans votre bloc catch avec l'instruction throwException(username, e);. Si vous vous attendez à obtenir l'utilisateur ou null sans aucune exception, ceci devrait ressembler à ceci:

public User getUserByUsernameOrNull(String username) {
    try{
        Query q = em.createNamedQuery(User.getUserByUsername);
        q.setParameter("username", username);
        return (User) q.getSingleResult();
    } catch(NoResultException e) {
        return null;
    }
}
32
stefanglase

Utilisez plutôt getResultList et vérifiez si la List est vide (a zéro élément). Sinon, la liste contient un élément et vous le renvoyez simplement.

11
ewernli

Vous rencontrez le comportement défini lorsque vous appelez getSingleResult et qu'aucune entrée n'a été trouvée: A NoResultException est renvoyé. Vous pouvez intercepter NoResultException dans la clause catch, car la transaction ne sera pas marquée en tant que restauration, lorsque JPA lève NoResultException. Ou vous pouvez utiliser getResultList () et vérifier si la taille est exactement "1", de sorte que vous sachiez que vous avez trouvé votre utilisateur. 

De plus, je ne renverrais pas "[null]" si l'utilisateur n'est pas trouvé, mais jette une exception UserNotFoundException vérifiée (à définir). Mais cela dépend du contrat de la méthode que vous allez implémenter.

3
Michael Konietzka

Michael a déclaré: "Vous pouvez intercepter NoResultException dans la clause catch, car la transaction ne sera pas marquée comme une annulation, lorsque JPA lève NoResultException.". Il semble que pour certaines implémentations jpa, la transaction NoResultException sera une transaction rollbak violant la spécification jpa, selon cet article: NoResultException marque l'annulation de la transaction

2
Mike

Si votre application utilise Spring Roo, la réponse la plus votée ne fonctionne pas: l'exception est capturée par les aspects et vous n'obtenez jamais la valeur désirable NoResultException. La seule façon de résoudre le problème consiste à utiliser getResultList et à vérifier zéro, un ou plusieurs résultats dans la List résultante, comme indiqué dans la deuxième réponse la plus votée.

0
koke24

Que fait la méthode throwException?

Existe-t-il une exception mais utilisez-vous le message de l’exception précédente?

0
JRL

Catch NoResultException dans le bloc try-catch et gérez-le conformément à vos exigences, telles que le renvoi d'une valeur null.

Un exemple de try-catch est détaillé dans le lien suivant: http://www.javabrahman.com/j2ee/jpa/no-result-exception/

0
Frank