queryForObject()は、レコードが見つからないときEmptyResultDataAccessExceptionをスローします
レガシープロジェクトを見直し、この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; } }