我提出疑问:
jdbcTemplate.query(sqlQueryForGetNodes, new Object[]{treeId, versionId}, rs -> {
NodeType nodeType = NodeType.get(rs.getInt("NodeTypeId"));
int nodeId = rs.getInt("NodeId");
SmbpTreeSwitchCase switchCase = new SmbpTreeSwitchCase();
switchCase.setSwitchConditionType(getSwitchTypeByNodeId(nodeId));
smbpTreeNodes.add(switchCase);
});
private SwitchConditionType getSwitchTypeByNodeId(int nodeId) {
String sqlQueryForGetSwitchTypeByNodeId = "SELECT SwitchConditionTypeId FROM RE.SwitchCondition sc WHERE sc.NodeId = ?";
return jdbcTemplate.query(sqlQueryForGetSwitchTypeByNodeId, resultSet -> {
return SwitchConditionType.get(resultSet.getInt("SwitchConditionTypeId"));
}, nodeId);
}
在这个查询中,我需要在方法getSwitchTypeByNodeId
中子查询另一个表来用数据填充对象。
但是我收到了一个错误:
org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [SELECT SwitchConditionTypeId FROM RE.SwitchCondition sc WHERE sc.NodeId = ?]; Before start of result set; nested exception is java.sql.SQLException: Before start of result set
我做错了什么?告诉我如何在jdbcTemplate
中正确地创建子查询?
答案 0 :(得分:1)
我认为你对JdbcTemplate.query
的两次调用中你的两个lambdas有不同的类型,因此Spring会对它们进行不同的处理。
第一个似乎有效的通话似乎使用了the overload of the JdbcTemplate.query
method String
,Object[]
和RowCallbackHandler
并返回void
。在这种情况下,lambda是RowCallbackHandler
,对结果集中的每一行调用一次。 Spring将把结果集从一行推进到下一行;它取决于你对每一行做些什么。
然而,第二个调用似乎使用the overload of JdbcTemplate.query
来获取String
,ResultSetExtractor
和varargs参数数组,并返回ResultSetExtractor
返回的任何内容。当使用ResultSetExtractor
时,Spring只会打电话给你一次,并期望你完成对结果集的所有处理。特别是,您需要检查结果集是否包含任何数据。
尝试将第二个lambda修改为以下内容:
return jdbcTemplate.query(sqlQueryForGetSwitchTypeByNodeId, resultSet -> {
if (resultSet.next()) {
return SwitchConditionType.get(resultSet.getInt("SwitchConditionTypeId"));
} else {
// SQL query returned no rows. TODO handle this somehow...
}
});