使用嵌套在另一个jdbcTemplate中的jdbcTemplate(在开始结果集之前)

时间:2018-01-21 17:44:18

标签: java spring jdbctemplate

我提出疑问:

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中正确地创建子查询?

1 个答案:

答案 0 :(得分:1)

我认为你对JdbcTemplate.query的两次调用中你的两个lambdas有不同的类型,因此Spring会对它们进行不同的处理。

第一个似乎有效的通话似乎使用了the overload of the JdbcTemplate.query method StringObject[]RowCallbackHandler并返回void。在这种情况下,lambda是RowCallbackHandler,对结果集中的每一行调用一次。 Spring将把结果集从一行推进到下一行;它取决于你对每一行做些什么。

然而,第二个调用似乎使用the overload of JdbcTemplate.query来获取StringResultSetExtractor和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...
            }
        });