J'utilise Jdbctemplate pour récupérer une seule valeur String à partir de la base de données. Voici ma méthode.
public String test() {
String cert=null;
String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN
where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
cert = (String) jdbc.queryForObject(sql, String.class);
return cert;
}
Dans mon scénario, il est tout à fait possible de ne PAS obtenir de réponse à ma requête, donc ma question est de savoir comment contourner le message d'erreur suivant.
EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
Il me semble que je devrais simplement récupérer un null au lieu de lancer une exception. Comment puis-je réparer cela? Merci d'avance.
la source
ResultSet.next()
appelé inutilement. L'utilisation d'unResultSetExtractor
est un outil beaucoup plus efficace dans ce cas.return null
danscatch(EmptyResultDataAccessException exception){ return null; }
?Vous pouvez également utiliser un
ResultSetExtractor
au lieu d'unRowMapper
. Les deux sont aussi simples l'un que l'autre, la seule différence est que vous appelezResultSet.next()
.Le
ResultSetExtractor
a l'avantage supplémentaire que vous pouvez gérer tous les cas où il y a plus d'une ligne ou aucune ligne renvoyée.MISE À JOUR : Plusieurs années plus tard et j'ai quelques astuces à partager.
JdbcTemplate
fonctionne parfaitement avec java 8 lambdas pour lesquels les exemples suivants sont conçus, mais vous pouvez assez facilement utiliser une classe statique pour obtenir la même chose.Bien que la question porte sur les types simples, ces exemples servent de guide pour le cas courant de l'extraction d'objets de domaine.
Tout d'abord. Supposons que vous ayez un objet compte avec deux propriétés pour plus de simplicité
Account(Long id, String name)
. Vous souhaiteriez probablement avoir unRowMapper
objet pour ce domaine.Vous pouvez maintenant utiliser ce mappeur directement dans une méthode pour mapper des
Account
objets de domaine à partir d'une requête (jt
est uneJdbcTemplate
instance).Excellent, mais maintenant nous voulons notre problème d'origine et nous utilisons ma solution originale en réutilisant le
RowMapper
pour effectuer le mappage pour nous.Génial, mais c'est un modèle que vous pouvez et voudrez répéter. Vous pouvez donc créer une méthode de fabrique générique pour en créer une nouvelle
ResultSetExtractor
pour la tâche.Créer un
ResultSetExtractor
maintenant devient trivial.J'espère que cela aidera à montrer que vous pouvez désormais combiner assez facilement des parties de manière puissante pour simplifier votre domaine.
MISE À JOUR 2 : À combiner avec une option facultative pour les valeurs facultatives au lieu de null.
Qui maintenant, lorsqu'il est utilisé, pourrait avoir les éléments suivants:
la source
Ce n'est pas une bonne solution car vous comptez sur des exceptions pour le flux de contrôle. Dans votre solution, il est normal d'obtenir des exceptions, il est normal de les avoir dans le journal.
la source
ResultSet.next()
appelé inutilement. L'utilisation d'unResultSetExtractor
est un outil beaucoup plus efficace dans ce cas.Ok, je l'ai compris. Je l'ai juste enveloppé dans une capture d'essai et renvoyé null.
la source
En fait, vous pouvez jouer avec
JdbcTemplate
et personnaliser votre propre méthode à votre guise. Ma suggestion est de faire quelque chose comme ceci:Cela fonctionne comme l'original
jdbc.queryForObject
, mais sansthrow new EmptyResultDataAccessException
quandsize == 0
.la source
UserMapper implements RowMapper<String>
.DataAccessUtils.singleResult(...)
c'est ce que je cherchais. ThxDepuis renvoyer une valeur null quand il n'y a pas de données est quelque chose que je veux faire souvent lors de l'utilisation de queryForObject, j'ai trouvé utile d'étendre JdbcTemplate et d'ajouter une méthode queryForNullableObject similaire à ci-dessous.
Vous pouvez maintenant l'utiliser dans votre code de la même manière que vous avez utilisé queryForObject
Je serais intéressé de savoir si quelqu'un d'autre pense que c'est une bonne idée?
la source
En utilisant Java 8 ou supérieur, vous pouvez utiliser un
Optional
et Java Streams.Vous pouvez donc simplement utiliser la
JdbcTemplate.queryForList()
méthode, créer un Stream et utiliserStream.findFirst()
qui renverra la première valeur du Stream ou un videOptional
:Pour améliorer les performances de la requête, vous pouvez ajouter
LIMIT 1
à votre requête, afin que pas plus d'un élément ne soit transféré de la base de données.la source
Vous pouvez utiliser une fonction de groupe pour que votre requête renvoie toujours un résultat. c'est à dire
la source
Dans Postgres, vous pouvez faire en sorte que presque n'importe quelle requête à valeur unique renvoie une valeur ou une valeur nulle en l'enveloppant:
et évitez ainsi la complexité de l'appelant.
la source
Depuis getJdbcTemplate (). QueryForMap attend une taille minimale de un, mais quand il retourne null, il affiche EmptyResultDataAccesso fix dis quand peut utiliser la logique ci-dessous
la source
J'avais traité de cela avant et j'avais posté dans les forums de printemps.
http://forum.spring.io/forum/spring-projects/data/123129-frustrated-with-emptyresultdataaccessexception
Le conseil que nous avons reçu était d'utiliser un type de SQlQuery. Voici un exemple de ce que nous avons fait en essayant d'obtenir une valeur d'une base de données qui pourrait ne pas être là.
Dans le DAO, nous appelons simplement ...
Pas clair sur les performances, mais cela fonctionne et est soigné.
la source
Pour Byron, vous pouvez essayer ceci.
la source
faire
travail, assurez-vous que votre jdbcTemplate est de type
la source
Nous pouvons utiliser query au lieu de queryForObject, la principale différence entre query et queryForObject est que la liste de retour de requête de Object (basée sur le type de retour du mappeur de lignes) et cette liste peut être vide si aucune donnée n'est reçue de la base de données tandis que queryForObject attend toujours qu'un seul objet soit extrait de la base de données ni null ni plusieurs lignes et au cas où le résultat est vide, queryForObject jette EmptyResultDataAccessException, j'avais écrit un code en utilisant une requête qui surmontera le problème de EmptyResultDataAccessException en cas de résultat nul.
la source
IMHO renvoyer un
null
est une mauvaise solution parce que maintenant vous avez le problème de l'envoyer et de l'interpréter au (probable) client frontal. J'ai eu la même erreur et je l'ai résolue en renvoyant simplement un fichierList<FooObject>
. J'ai utiliséJDBCTemplate.query()
.Au front end (client web angulaire), j'examine simplement la liste et si elle est vide (de longueur nulle), je la traite comme aucun enregistrement trouvé.
la source
J'attrape juste cette "EmptyResultDataAccessException"
alors vous pouvez vérifier:
la source