JdbcTemplate中queryForObject方法返回空结果或不正确结果数量的解决方法

  在使用Spirng提供的JdbcTemplate中名为queryForObject API进行数据库查询时有时会抛出如下异常:

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

(不正确的结果大小,预期是1,实际为0)

或者:

org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 2 

(不正确的结果大小,预期是1,实际为2)

  在解决这些异常之前,我们首先来看看queryForObject API的源代码,假设我们调用的是queryForObject(String sql,Class requiredType)。

JdbcTemplate.class

 1 public <T> T queryForObject(String sql, Class<T> requiredType) 
 2         throws DataAccessException 
 3 {return queryForObject(sql, getSingleColumnRowMapper(requiredType));}
 4 
 5 public <T> T queryForObject(String sql, RowMapper<T> rowMapper) 
 6         throws DataAccessException {
 7     List<T> results = query(sql, rowMapper);
 8     return DataAccessUtils.requiredSingleResult(results);
 9 }
10 
11 public <T> List<T> query(String sql, RowMapper<T> rowMapper) 
12         throws DataAccessException {
13     return query(sql, new RowMapperResultSetExtractor<T>(rowMapper));
14 }
15 
16 public <T> T query(final String sql, final ResultSetExtractor<T> rse) 
17         throws DataAccessException {
18     Assert.notNull(sql, "SQL must not be null");
19     Assert.notNull(rse, "ResultSetExtractor must not be null");
20     if (logger.isDebugEnabled()) {
21         logger.debug("Executing SQL query [" + sql + "]");
22     }
23     class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
24         public T doInStatement(Statement stmt) throws SQLException {
25             ResultSet rs = null;
26             try {
27                 rs = stmt.executeQuery(sql);
28                 ResultSet rsToUse = rs;
29                 if (nativeJdbcExtractor != null) {
30                     rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
31                 }
32                 return rse.extractData(rsToUse);
33             }
34             finally {
35                 JdbcUtils.closeResultSet(rs);
36             }
37         }
38         public String getSql() {
39             return sql;
40         }
41     }
42     return execute(new QueryStatementCallback());
43 }

DataAccessUtil.class

 1 public static <T> T requiredSingleResult(Collection<T> results) 
 2         throws IncorrectResultSizeDataAccessException {
 3     int size = (results != null ? results.size() : 0);
 4     if (size == 0) {
 5         throw new EmptyResultDataAccessException(1);
 6     }
 7     if (results.size() > 1) {
 8         throw new IncorrectResultSizeDataAccessException(1, size);
 9     }
10     return results.iterator().next();
11 }

  通过阅读源代码,可以清楚地看到在DataAccessUtils.class中requiredSingleResult方法中,当结果集合的size为0或者大于1时,就会抛出以上两个异常。

  解决方法有两个:

扫描二维码关注公众号,回复: 5315925 查看本文章

  (1)通过修改数据库:删除数据库中对应名称(column)相同的记录,留下只剩"1"条。

  (2)通过更换方法:使用query方法返回list对象(该方法能返回所有查询记录)

1    public transient List query(String sql, RowMapper rowMapper, Object args[])
2         throws DataAccessException
3     {
4         return (List)query(sql, args, ((ResultSetExtractor) (new RowMapperResultSetExtractor(rowMapper))));
5     }

  

猜你喜欢

转载自www.cnblogs.com/codingmengmeng/p/10431674.html