You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JdbcTemplate query方法引用歧义报错,本地克隆项目无法运行求助

问题描述

从Git克隆的项目在其他机器可正常运行,但本地启动时出现报错,且多处类和位置存在类似问题。已尝试更换不同JDK版本、调整Gradle配置及配置Tomcat,问题仍未解决。相关代码及报错信息如下:

@Override
public Long findLastPolicy(long policyId) {
    Long firstPolicy = findFirstPolicy(policyId);
    if (firstPolicy == null) {
        return null;
    }
    final List<Long> lastPolicyId = new ArrayList<>();
    jdbcTemplate.query("select id from ( " +
            " select qsn3.fk_plc id from cmn.tbi_questionnaire_tree qsn3 where qsn3.fk_plc_anct = ?  and qsn3.fk_plc is not null" +
            " order by qsn3.endorsement_sequence desc " +
            " ) where rowNum < 2", resultSet -> {
        lastPolicyId.add(resultSet.getLong("id"));
    }, firstPolicy);
    return lastPolicyId.get(0);
}

报错信息

  • error: reference to query is ambiguous
    jdbcTemplate.query("select id from ( " +
    ^
    both method query(String,ResultSetExtractor,Object...) in JdbcTemplate and method query(String,RowCallbackHandler,Object...) in JdbcTemplate match
    where T is a type-variable:
    T extends Object declared in method query(String,ResultSetExtractor,Object...)

  • error: incompatible types: cannot infer type-variable(s) T
    jdbcTemplate.query("select id from ( " +
    ^
    (argument mismatch; bad return type in lambda expression
    missing return value)
    where T is a type-variable:
    T extends Object declared in method query(String,ResultSetExtractor,Object...)

解决方案

根因分析

Lambda表达式的写法让编译器无法区分目标类型是ResultSetExtractor还是RowCallbackHandler,导致方法调用歧义。前者的extractData方法需要返回值,后者的processRow方法无返回值,你的Lambda没有返回值,但编译器仍无法明确匹配对应方法。

修复方案

方案1:显式指定Lambda目标类型

把Lambda强制转为RowCallbackHandler,让编译器明确调用对应重载方法:

jdbcTemplate.query("select id from ( " +
        " select qsn3.fk_plc id from cmn.tbi_questionnaire_tree qsn3 where qsn3.fk_plc_anct = ?  and qsn3.fk_plc is not null" +
        " order by qsn3.endorsement_sequence desc " +
        " ) where rowNum < 2", (RowCallbackHandler) resultSet -> {
    lastPolicyId.add(resultSet.getLong("id"));
}, firstPolicy);

方案2:改用更简洁的queryForObject方法

既然只需要获取单条数据的ID,直接使用queryForObject可以避免手动维护List,代码更简洁:

return jdbcTemplate.queryForObject(
        "select qsn3.fk_plc from cmn.tbi_questionnaire_tree qsn3 where qsn3.fk_plc_anct = ? and qsn3.fk_plc is not null order by qsn3.endorsement_sequence desc where rownum < 2",
        Long.class,
        firstPolicy
);

方案3:统一Spring版本

项目在其他机器正常、本地报错,大概率是Spring JDBC依赖版本不一致导致方法签名差异。核对其他机器的Gradle/Maven依赖中Spring相关版本,确保本地依赖版本完全一致。例如在Gradle中锁定版本:

ext {
    springVersion = "5.3.20" // 替换为其他机器使用的实际版本
}
dependencies {
    implementation "org.springframework:spring-jdbc:${springVersion}"
    // 其他Spring相关依赖统一使用上述版本
}

内容的提问来源于stack exchange,提问作者Aziz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:25:18