Spring Boot JpaRepository参数数量不匹配异常求助
解决Spring Boot JpaRepository UPSERT时的参数不匹配异常
问题根源
你遇到的java.lang.IllegalArgumentException: At least 2 parameter(s) provided but only 1 parameter(s) present in query异常,核心原因是错误使用了@SQLInsert/@SQLUpdate注解:这些注解是Hibernate用来覆盖JpaRepository默认save()/update()方法SQL的扩展注解,不能直接用来定义自定义业务方法。当你在自定义方法上标注这些注解时,Hibernate会错误地将其解析为默认CRUD操作的SQL模板,导致参数绑定逻辑混乱,最终抛出参数不匹配的异常。
另外你之前的SQL写法也存在逻辑错误:比如用INSERT ... SELECT的方式,只有当记录已存在时才会执行插入,完全违背了UPSERT(不存在则插入,存在则更新)的核心逻辑。
正确解决方案
使用@Query配合原生SQL实现UPSERT逻辑,以下是两种可行的实现方式:
方式一:返回影响行数(推荐)
public interface ordini_lista_prodottiRepository extends JpaRepository<ordini_lista_prodotti, String> { @Modifying @Query(value = "INSERT INTO ordini_lista_prodotti (lista_ordini_idord, lista_prodotti_codprod, prototype) " + "VALUES (:idord, :codprod, :prototype) " + "ON CONFLICT (lista_ordini_idord, lista_prodotti_codprod) " + "DO UPDATE SET prototype = :prototype", nativeQuery = true) int upsertPrototype(@Param("idord") String idord, @Param("codprod") String codprod, @Param("prototype") String prototype); }
@Modifying:标记该方法是数据修改操作,而非查询nativeQuery = true:使用原生SQL语法(因为ON CONFLICT是PostgreSQL特有的UPSERT语法)- 逻辑说明:用
VALUES直接插入新记录,当主键/唯一键冲突时,执行更新操作;返回值为受影响的行数(插入成功返回1,更新成功返回1)
方式二:返回操作后的实体
如果需要获取操作后的实体数据,可以添加RETURNING子句:
public interface ordini_lista_prodottiRepository extends JpaRepository<ordini_lista_prodotti, String> { @Modifying @Query(value = "INSERT INTO ordini_lista_prodotti (lista_ordini_idord, lista_prodotti_codprod, prototype) " + "VALUES (:idord, :codprod, :prototype) " + "ON CONFLICT (lista_ordini_idord, lista_prodotti_codprod) " + "DO UPDATE SET prototype = :prototype " + "RETURNING *", nativeQuery = true) ordini_lista_prodotti upsertPrototypeAndReturn(@Param("idord") String idord, @Param("codprod") String codprod, @Param("prototype") String prototype); }
额外注意事项
- 确保数据库表
ordini_lista_prodotti已经在lista_ordini_idord和lista_prodotti_codprod上创建了唯一约束(这是ON CONFLICT生效的前提) - 实体类
ordini_lista_prodotti的字段映射要和数据库表字段完全对应(比如下划线命名和驼峰命名的映射,可通过@Column注解指定) - 自定义方法名建议用
upsertPrototype这类语义明确的名称,避免模糊命名
内容的提问来源于stack exchange,提问作者Stefano Giammori
相关产品推荐
相关产品推荐

