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

Spring Data JPA @Query使用::numeric设置小数精度报语法错误

问题根因

Spring Data JPA解析@Query注解内的查询语句时,默认将所有冒号:识别为命名参数占位符的起始标记。PostgreSQL专属的::类型转换语法中的冒号会被JPA误判为参数前缀,无法匹配到对应命名参数时就会抛出语法错误,和PostgreSQL侧的SQL语法正确性无关。

解决方法
  • 优先方案:使用标准SQL的CAST函数替代::类型转换语法
    该写法无特殊字符,不会触发JPA的参数解析规则,同时符合SQL标准,跨数据库兼容性更好。修改后的代码如下:
    @Query(value = "SELECT CAST(AVG(feedback_rating) AS numeric(10,2)) FROM app_customer_feedback WHERE " +
            "created_date >= to_timestamp(:dateFrom, 'yyyy-mm-dd hh24:mi:ss') AND " +
            "created_date < to_timestamp(:dateTo, 'yyyy-mm-dd hh24:mi:ss')", nativeQuery = true)
    Double getAverageByDateRange(@Param("dateFrom") String dateFrom, @Param("dateTo") String dateTo);
    
  • 备选方案:转义非参数用途的冒号
    如果需要保留PostgreSQL的::简写语法,可在非参数的冒号前添加双反斜杠转义,告知JPA该部分不属于参数占位符,修改后的类型转换片段为AVG(feedback_rating)\\:\\:numeric(10, 2),完整代码如下:
    @Query(value = "SELECT AVG(feedback_rating)\\:\\:numeric(10, 2) FROM app_customer_feedback WHERE " +
            "created_date >= to_timestamp(:dateFrom, 'yyyy-mm-dd hh24:mi:ss') AND " +
            "created_date < to_timestamp(:dateTo, 'yyyy-mm-dd hh24:mi:ss')", nativeQuery = true)
    Double getAverageByDateRange(@Param("dateFrom") String dateFrom, @Param("dateTo") String dateTo);
    

提示:转义写法的生效逻辑和Spring Data JPA版本绑定,若老版本下转义失效,直接使用CAST方案即可。

内容的提问来源于stack exchange,提问作者Golam Wasy Arnob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:36:23