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

