我正在尝试使用IN
注释与@Query
注释JPA
。我收到以下错误: -
antlr.NoViableAltException: unexpected AST node: {vector}
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2112)
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException:
unexpected AST node: {vector}
[ [select o FROM Stock o where (:productlist_0_, :productlist_1_, :productlist_2_, :productlist_3_ is null or o.productsid IN (:productlist_0_, :productlist_1_, :productlist_2_, :productlist_3_) )
我的Java代码如下: -
@Query("SELECT o FROM Stock o where (:productlist is null or o.productsid IN (:productlist) ) ")
List<Stockdiary> getAllStock(Pageable pageable, @Param("productlist") List<Products> productlist)
当productlist
中只包含单个项目时,此功能正常。但当我在productlist
中有多个项目时,查询如下所示并出现错误: -
select o FROM Stock o where (:productlist_0_, :productlist_1_, :productlist_2_, :productlist_3_ is null or o.productsid IN (:productlist_0_, :productlist_1_, :productlist_2_, :productlist_3_
我看过这个link,但这种解决方法对我不起作用。
我尝试使用带括号和不带括号的:productlist
。
答案 0 :(得分:5)
我遇到了和你一样的问题,解决方案非常简单。经过一番努力,我发现下一个版本工作正常:
@Query("select c from Cruise c where" +
" (:categoryId is null or c.category.id = :categoryId)" +
" and ((:portsIds) is null or c.port.id in (:portsIds))")
List<Cruise> findByRequestQuery(@Param("portsIds") List<Long> portsIds,
@Param("categoryId") Long categoryId);
正如这里提到的:https://stackoverflow.com/a/24551530/6629515你应该在集合参数中添加括号,对我而言,如果为每个集合参数添加括号,它会起作用:
(:portsIds)
结果SQL查询部分看起来像:
where (? is null or cruise0_.category_id=?) and ((? , ? , ?) is null or cruise0_.port_id in (? , ? , ?))
答案 1 :(得分:0)
作为一种解决方法,我使用了另一个变量进行null验证,因为括号并不适用于所有DB。例如:
@Query("SELECT o FROM Stock o where (:hayProductos is null or o.productsid IN (:productlist) ) ")
List<Stockdiary> getAllStock(Pageable pageable, @Param("productlist") List<Products> productlist, @Param("hayProductos") Boolean hayProductos)
答案 2 :(得分:0)
由于我无法评价@Alex Efimov的答案,所以我只是基于@Alex Efimov的答案
对于@Cat H的问题(SQLException:操作数应包含1列)
您可以使用这种方式(添加一个布尔变量以在空集合时忽略查询):
基于@Alex Efimov的代码:
boolean ignoreQueryPortsIds = CollectionUtils.isEmpty(portsIds);
@Query("select c from Cruise c where" +
" (:categoryId is null or c.category.id = :categoryId)" +
" and (:ignoreQueryPortsIds is true or c.port.id in :portsIds)")
List<Cruise> findByRequestQuery(@Param("portsIds") List<Long> portsIds,
@Param("categoryId") Long categoryId,
@Param("ignoreQueryPortsIds ") boolean ignoreQueryPortsIds );
注意:您必须在is true
之后添加:ignoreQueryPortsIds
,否则jpa无法解析您的HQL
答案 3 :(得分:0)
我解决了同样的问题,以解决o.productsid IN (:productlist) OR :productlist is null
的情况
@Query("SELECT o FROM Stock o where (o.productsid IN (:productlist) OR :productlist is null ) ")
List<Stockdiary> getAllStock(Pageable pageable, @Param("productlist") List<Products> productlist)