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時,就會拋出以上兩個異常。

  解決方法有兩個:

  (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     }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM