レガシープロジェクトを見直し、このSpringのJDBCコードスニペットを見つけました:

  public User getUser(String username) {

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

    return getJdbcTemplate().queryForObject(
                sql,
                new Object[]{ username },
        new RowMapper<UserAttempts>() {
        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;
        }

    });

  }

問題

開発者は、レコードが見つからないときにnullを返すと仮定します。

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

問題は、レコードが見つからないときにnullを返す代わりに、Springが `EmptyResultDataAccessException`をスローしたことです。

JdbcTemplate .java

package org.springframework.jdbc.core;

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {

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

DataAccessUtils.java

package org.springframework.dao.support;

public abstract class DataAccessUtils {

   //...
    public static <T> T requiredSingleResult(Collection<T> 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バージョン3.2.8.RELEASE

解決策

nullを返すことはかなり標準的です。なぜSpringが `EmptyResultDataAccessException`をスローしたいのでしょうか?これを修正するには、例外をキャッチしてnullを返します。

  public User getUser(String username) {

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

    try {
          User user = getJdbcTemplate().queryForObject(
                 sql,
                 new Object[]{ username },
         new RowMapper<UserAttempts>() {
         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;
    }
  }