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
相关产品推荐
相关产品推荐

