【问题标题】:JPA QuerySyntaxException: unexpected AST node: {vector} For In conditionJPA QuerySyntaxException:意外的 AST 节点:{vector} For In 条件
【发布时间】:2017-01-04 19:58:48
【问题描述】:

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

【问题讨论】:

  • 当参数是集合时,您的 JPA 提供程序似乎无法处理“:param IS NULL”,或者可能是它与“OR”的组合。因此,将其作为提供程序的错误提出。

标签: java hibernate jpa


【解决方案1】:

我遇到了和你一样的问题,解决方法很简单。经过解决后,我发现下一个变体工作正常:

@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 列问题

请在此处阅读:https://stackoverflow.com/a/51958547/1522490

简而言之:使用coalesce(:portsIds, null) is null

【讨论】:

  • 但如果我使用 MySQL,我会收到错误 SQLException: Operand should contain 1 column(s)。如何解决这个问题?
  • @CatH 请提供您的代码示例,我会尝试。我展示了 Postgresql 的示例,这里可能有些不同。
  • 也不适用于 db2。 (? , ? , ?) is null 语法无效
  • 关于java.sql.SQLException: Operand should contain 1 column(s)。请参阅下面的@popgeh 评论☟
  • @Oleksandr H:我在上面添加了解决方案
【解决方案2】:

由于我无法对@Alex Efimov 的答案发表评论,所以我只是根据@Alex Efimov 的答案来写答案

对于@Cat H 的问题(SQLException: Operand should contain 1 column(s))

您可以使用这种方式(添加一个布尔变量以在为空集合时忽略查询):
基于@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 );

注意:您必须在 :ignoreQueryPortsIds 之后添加 is true 否则 jpa 无法解析您的 HQL

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,我修复了它,以扭转 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)
    

    【讨论】:

    • :productlist 为 null 如果我们使用整数列表,这将产生问题
    【解决方案4】:

    作为一种解决方法,我使用另一个变量进行空验证,因为括号不适用于所有数据库。例如:

        @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)
    

    【讨论】:

    • 它是布尔值。你可以在那里发送一个 true/false 而不是 null
    猜你喜欢
    • 2021-12-05
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2018-06-26
    • 2020-05-02
    相关资源
    最近更新 更多