如何处理ResultSet返回0、1或2行时抛出EmptyResultDataAccessException的问题
问题根因
1. 异常不是你写的ResultSet处理代码抛出的
你遇到的org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0是Spring JDBC模块的内置异常,触发时机是你调用了Spring提供的要求查询结果必须恰好返回1行的查询API(比如JdbcTemplate.queryForObject()、JdbcTemplate.queryForMap()等),当查询实际返回0行或者大于1行时,Spring会在封装结果的阶段直接抛出异常,根本不会走到你自己编写的ResultSet处理逻辑里。
你提到返回2行时运行正常,说明你查询2行时用的是支持多行结果的API(比如query()、queryForList()),而查询0/1行时错误调用了要求单结果的API。
2. 你的ResultSet处理代码本身也存在兼容问题
就算调整查询API后能拿到ResultSet,你的代码还有隐含bug:
JDBC默认创建的ResultSet是TYPE_FORWARD_ONLY类型,只允许指针从前往后单向移动,不支持回退操作。你在if判断里调用resultSet.next()将指针移动到第一行后,else分支里执行的resultSet.beforeFirst()回退指针操作会直接抛出SQLException。
修复方案
- 第一步:统一使用支持多行结果的Spring JDBC查询API获取结果集,比如
JdbcTemplate.query(),避免Spring提前抛结果行数校验异常。 - 第二步:调整ResultSet处理逻辑,避免回退指针,优化后的代码示例如下:
Map<String, Integer> results = new HashMap<>(); // 初始化默认值,不需要先判断是否为空 results.put("count1", 0); results.put("count2", 0); // 直接遍历结果集即可,0行的话不会进入循环,默认值保留 while (resultSet.next()) { results.put(resultSet.getInt("column1") == 0 ? "count1" : "count2", resultSet.getInt("column2")); }
这段代码可以同时兼容0、1、2行的返回结果,也不需要调用beforeFirst()做指针回退,兼容默认的forward-only类型ResultSet。
内容的提问来源于stack exchange,提问作者wangb
相关产品推荐
相关产品推荐

