PostgreSQL与JPA报错:不支持混合?参数与?1形式的解决方案咨询
解决方案:JPA中JSONB路径查询的参数占位符冲突问题
问题核心是PostgreSQL的JSONB路径表达式里的?是过滤谓词的语法,和JPA原生查询的参数占位符?1语法冲突,导致抛出Mixing of ? parameters and other forms like ?1 is not supported错误。以下是两种可行的解决方式:
方法一:使用JSONB路径变量(推荐,无SQL注入风险)
通过PostgreSQL的JSONB路径变量功能,将正则表达式参数作为变量传入路径表达式,避免直接在路径里写JPA参数占位符:
最终JPA查询代码
@Query(nativeQuery = true, value = "SELECT DISTINCT jsonb_path_query(jsonb_column, '$[*] ? (@.events[*] like_regex $pattern flag \"i\")', jsonb_build_object('pattern', ?1)) " + "FROM my_table") List<JsonNode> findMatchingEvents(String regexPattern);
原理说明
- 路径表达式里用
$pattern定义变量,替代原来硬编码的正则字符串 - 用
jsonb_build_object('pattern', ?1)将JPA的参数?1包装成JSON对象,作为jsonb_path_query的第三个参数传入,实现参数绑定 - 完全避开了路径里的
?和JPA参数占位符的冲突,同时保证参数安全,无SQL注入风险
方法二:安全拼接路径字符串(需注意SQL注入)
如果不想用路径变量,可以通过PostgreSQL的字符串拼接函数构建完整的路径表达式,确保JPA参数只出现在字符串拼接部分:
JPA查询代码
@Query(nativeQuery = true, value = "SELECT DISTINCT jsonb_path_query(jsonb_column, concat('$[*] ? (@.events[*] like_regex \"', ?1, '\" flag \"i\")')) " + "FROM my_table") List<JsonNode> findMatchingEvents(String regexPattern);
注意事项
- 此方法依赖
concat函数拼接路径字符串,必须确保传入的regexPattern是可信的,否则存在SQL注入风险 - 如果参数包含特殊字符(比如双引号),需要提前做转义处理,否则会破坏路径表达式的语法
内容的提问来源于stack exchange,提问作者bonanzaa
相关产品推荐
相关产品推荐

