157 votes

JPA getSingleResult () ou null

J'ai une méthode insertOrUpdate qui insère une entité quand elle n'existe pas ou la met à jour si c'est le cas. Pour l'activer, je dois trouverByIdAndForeignKey, si elle a renvoyé une insertion nulle sinon une mise à jour. Le problème est comment puis-je vérifier s'il existe? Alors j'ai essayé getSingleResult. Mais il jette une exception si le

 public Profile findByUserNameAndPropertyName(String userName, String propertyName) {
    String namedQuery = Profile.class.getSimpleName() + ".findByUserNameAndPropertyName";
    Query query = entityManager.createNamedQuery(namedQuery);
    query.setParameter("name", userName);
    query.setParameter("propName", propertyName);
    Object result = query.getSingleResult();
    if(result==null)return null;
    return (Profile)result;
}
 

mais "getSingleResult" lève une exception.

Merci

293voto

cletus Points 276888

Lancer une exception est combien de getSingleResult() indique qu'il ne peut pas être trouvé. Personnellement, je ne peux pas tenir ce genre d'API. C'forces de fausse manipulation d'exception pour aucun avantage réel. Vous avez juste à placer le code dans un bloc try-catch.

Sinon, vous pouvez demander une liste et de voir si son vide. Qui ne lance pas d'exception. En fait depuis que vous ne faites pas une clé primaire de recherche, techniquement, il pourrait y avoir plusieurs résultats (même si, à la fois, ou de la combinaison de vos clés étrangères ou des contraintes rend cela impossible en pratique) donc c'est probablement la solution plus appropriée.

35voto

Eugene Katz Points 2784

J'ai encapsulé la logique dans la méthode d'assistance suivante.

 public class JpaResultHelper {
    public static Object getSingleResultOrNull(Query query){
        List results = query.getResultList();
        if (results.isEmpty()) return null;
        else if (results.size() == 1) return results.get(0);
        throw new NonUniqueResultException();
    }
}
 

24voto

Rodrigo IronMan Points 51

voici une bonne option pour le faire:

 public static <T> T getSingleResult(Query query) {
    query.setMaxResults(1);
    List<?> list = query.getResultList();
    if (list == null || list.size() == 0) {
        return null;
    }
    return (T) list.get(0);
}
 

19voto

heenenee Points 11

Spring a une méthode d’utilité pour cela:

 TypedQuery<Profile> query = em.createNamedQuery(namedQuery, Profile.class);
...
return org.springframework.dao.support.DataAccessUtils.singleResult(query.getResultList());
 

6voto

Emmanuel Touzery Points 1677

Voici une version typée / générique, basée sur l'implémentation de Rodrigo IronMan:

  public static <T> T getSingleResultOrNull(TypedQuery<T> query) {
    query.setMaxResults(1);
    List<T> list = query.getResultList();
    if (list.isEmpty()) {
        return null;
    }
    return list.get(0);
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X