我目前正在寻找异常的解决方案
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter with that position [1] did not exist;
我当前的@Query
注释是:
@Query(
nativeQuery = true,
value = "SELECT * FROM thgcop_order_placement WHERE \"order_info\" @> '{\"parentOrderNumber\":\" :param \"}'")
我猜position [1] did not exist
来自双引号加双引号加单引号。
我该如何做到这一点?
查询使用的是Postgres JSONB
数据类型。列定义为ORDER_INFO JSONB
以下本机查询在Postgres客户端中运行良好:
SELECT * FROM thgcop_order_placement
WHERE "order_info" @> '{"parentOrderNumber":"ORD123"}'
答案 0 :(得分:5)
除了下面的内容之外,以上所有内容都没有,
服务层代码: -
OrderInfo orderInfo = new OrderInfo();
orderInfo.setParentOrderNumber("ORD123");
....
String param = objectMapper.writeValueAsString(orderInfo);
List<Order> list = jpaRepository.getByParentOrderNumber(param);
JpaRepository.java代码: -
@Query(nativeQuery = true, value = "select * from thgcop_order_placement where order_info @> CAST(:condition as jsonb)")
List<Order> getByParentOrderNumber(@Param("condition") String parentOrderNumber);
这就是我实现结果的方式。我希望这对所有热心的 !!
非常有帮助谢谢大家的帮助!!!
答案 1 :(得分:0)
尝试按以下方式绑定参数
@Query(nativeQuery = true, value = "SELECT * FROM thgcop_order_placement"
+ " WHERE \"order_info\" @> '{\"parentOrderNumber\":\" ?1 \"}'")
答案 2 :(得分:0)
TL; DR :首先使用Bind Parameter和普通JDBC。然后转到Spring Data,可能会回到自定义实现上。
你在这里面临许多层面的问题。
让我们暂时忽略Spring Data。 您展示的语句与您尝试使用Spring Data构建的语句非常不同,因为它不包含绑定变量。 而不是
SELECT * FROM thgcop_order_placement WHERE "order_info" @> '{"parentOrderNumber":"ORD123"}'
我们应该将它与
进行比较SELECT * FROM thgcop_order_placement WHERE "order_info" @> '{"parentOrderNumber": ? }'
请注意,我们正在丢失引号,因为它们表示文字字符串但我们不提供文字字符串而是绑定参数。
我还没有发现任何迹象表明你可以在JSON表达式的部分中使用绑定参数。因此,我们需要使用:
而不是上述声明SELECT * FROM thgcop_order_placement WHERE "order_info" @> ?
当然,bind参数应该包含完整的JSON表达式
不幸的是,这似乎不起作用,因为现在Postgres认为绑定参数是VARCHAR
而不是JSON表达式。见https://blog.2ndquadrant.com/processing-json/。我认为正确的版本应该是
SELECT * FROM thgcop_order_placement WHERE "order_info" @> ?::json
但是,我也无法使用它。
在任何情况下,您都可以将参数转换为JSON结构。 通常我建议使用SpEL表达式。但它不起作用,因为Spring Data在SpEL表达式中需要花括号并将它们视为SpEL表达式的结束。
如果您使用简单的JDBC连接或JdbcTemplate
获得此类内容,则可以开始考虑@Query
注释。
@Query(
value= "SELECT * FROM thgcop_order_placement WHERE \"order_info @> :name::json",
nativeQuery = true)
这可能会引发更多问题,因为Spring Data会考虑参数名称的::json
部分。如果是这种情况,您将不得不依赖自定义实施。
I ran a couple of experiments, which you can look at and play with here.
答案 3 :(得分:0)
我也被困在同一个问题上一段时间。似乎springboot在解析以字符串格式存在的查询时搞砸了。但是,这是我找到的解决方案,可以直接在存储库中作为本机查询使用:
order_info
的类型为jsonb
,因此可以将搜索到的值转换为jsonb值。{"parentOrderNumber":"ORD123"}
String searchString = "{\"parentOrderNumber\":\"ORD123\"}"
@Query(
value = "SELECT * from thgcop_order_placement where ((?1\\:\\:jsonb) <@ (order_info\\:\\:jsonb))",
nativeQuery=true
)
List<Order> getByParentOrderNumber(String searchString);
在哪里
?1
替换为searchString
的值。::
是类型转换运算符,使用它我们将传递的参数(searchString
)显式转换为jsonb
。因此,在尝试进行搜索之前,值{\"parentOrderNumber\":\"ORD123\"}
被转换为jsonb
。order_info
的值显式类型转换为jsonb
。<@
运算符检查列值中是否包含搜索字符串。在服务级别,我们只需要这样做:
String orderNumber = "-- some order value e.g. ORD123 --"
String searchString = "{\"parentOrderNumber\":\"" + orderNumber + "\"}"
List<Order> list = jpaRepository.getByParentOrderNumber(searchString);
有关Postgres JSON运算符的更多详细信息,可以在以下官方文档中找到:https://www.postgresql.org/docs/9.5/functions-json.html