queryForObject () lève une exception EmptyResultDataAccessException lorsque l’enregistrement est introuvable

queryForObject () lève EmptyResultDataAccessException lorsque l'enregistrement est introuvable

Examiner un projet hérité et trouver ces extraits de code Spring JDBC:

  public User getUser(String username) {

    String sql = "SELECT * FROM USER WHERE username = ?";

    return getJdbcTemplate().queryForObject(
                sql,
                new Object[] { username },
        new RowMapper() {
        public UserAttempts mapRow(ResultSet rs, int rowNum) throws SQLException {

            User user = new User();
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setAge(rs.getInt("age"));
            user.setLastModified(rs.getDate("lastModified"));

            return user;
        }

    });

  }

Problème

Le développeur suppose qu'il renverra un null lorsque l'enregistrement est introuvable.

    User user = abc.getUser("example");
    if(user == null){
        //...do something
    }

Le problème est que Spring lance unEmptyResultDataAccessException, au lieu de renvoyer un null lorsque l'enregistrement est introuvable.

JdbcTemplate .java

package org.springframework.jdbc.core;

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {

     //...
    public  T queryForObject(String sql, Object[] args,
        RowMapper rowMapper) throws DataAccessException {
    List results = query(sql, args, new RowMapperResultSetExtractor(rowMapper, 1));
    return DataAccessUtils.requiredSingleResult(results);
    }

DataAccessUtils.java

package org.springframework.dao.support;

public abstract class DataAccessUtils {

    //...
    public static  T requiredSingleResult(Collection results)
         throws IncorrectResultSizeDataAccessException {
    int size = (results != null ? results.size() : 0);
    if (size == 0) {
        throw new EmptyResultDataAccessException(1);
    }
    if (results.size() > 1) {
        throw new IncorrectResultSizeDataAccessException(1, size);
    }
    return results.iterator().next();
    }

P.S Spring version 3.2.8.RELEASE

Solution

Renvoyer null est assez standard, demandez-vous pourquoi Spring veut lancer unEmptyResultDataAccessException? Pour résoudre ce problème, interceptez simplement l'exception et renvoyez null.

  public User getUser(String username) {

    String sql = "SELECT * FROM USER WHERE username = ?";

    try {
          User user = getJdbcTemplate().queryForObject(
                 sql,
                 new Object[] { username },
         new RowMapper() {
         public UserAttempts mapRow(ResultSet rs, int rowNum) throws SQLException {

            User user = new User();
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setAge(rs.getInt("age"));
            user.setLastModified(rs.getDate("lastModified"));

            return user;
         }
                });
          return user;

    } catch (EmptyResultDataAccessException e) {
        return null;
    }
  }