JPA QuerySyntaxException:意外的AST节点:{vector} For In condition

时间:2016-08-28 19:52:52

标签: java hibernate jpa

我正在尝试使用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

4 个答案:

答案 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)