【问题标题】:Spring JPA with pageable and subquery causing query syntax error带有可分页和子查询的 Spring JPA 导致查询语法错误
【发布时间】:2021-09-17 01:45:16
【问题描述】:

我有一个如下定义的 Spring Data Repository:

public interface InvoiceRepository extends JpaRepository<Invoice, Long> {
   @Query(value = "select i.id as id,  " +
            "i.invoiceStatus as invoiceStatus, " +
            "(select sum(r.id) from Invoice r ) as paid " +
            "from Invoice i ")
    Page<InvoiceQuery> getInvoicesByStatusAndName(Pageable pageable);

}

上面给出的子查询不是真实的,但这个简单的查询有助于重现问题。

当我的 springboot(2.4.5) 应用程序启动时,我得到以下异常

引起:java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException:期待 EOF, 在第 1 行第 62 列附近找到 ')' [select count(r) from com.anish.webacc.orm.entities.Invoice r) 支付自 com.anish.webacc.orm.entities.Invoice i] 在 org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]

如果我改变了

Page<InvoiceQuery> getInvoicesByStatusAndName(Pageable pageable);

List<InvoiceQuery> getInvoicesByStatusAndName(Pageable pageable);

然后它可以完美运行(没有分页部分)。

InvoiceQuery 是一个投影接口-

public interface InvoiceQuery {
    Long getId();
    InvoiceStatus getInvoiceStatus();
    Double getPaid();
}

生成的查询似乎不正确 - 出于某种原因,我怀疑子查询中的 paratheses 导致了问题。如果我删除子查询我没有问题

这是我第一次尝试进行分页,所以我可能会在这里做一些非常愚蠢的事情 - 任何帮助将不胜感激。

谢谢 -anish

【问题讨论】:

  • 你为什么需要一个子查询呢?此外,该子查询很奇怪,为什么表的id 上有sum
  • 我同意,子查询是微不足道和愚蠢的,但它应该仍然有效!真正的子查询很复杂,但没有必要把它放在这里——这个简单的查询突出了问题。
  • @anish 问题在于 count() 查询,当您使用内部查询时它无法派生它。检查我的答案

标签: hibernate spring-data-jpa spring-data


【解决方案1】:

问题是当您使用内部查询时,Spring 数据 JPA 无法派生计数查询。查看您何时希望返回类型为 Page , Page - 将总页数和总元素作为它与分页结果一起返回的两件事。

   int getTotalPages();

    long getTotalElements();

因此,要获得这两个东西,即具有您的条件的总元素和给定页面大小的总页数,它必须派生一个 count() 查询,在您的情况下,它无法派生该 count() 查询。您可以在“@Query”注释中明确指定计数查询。如下所示

  @Query(value = "select new com.example.package.InvoiceQuery(i.id as id,i.invoiceStatus as invoiceStatus,(select sum(r.id) from Invoice r ) as paid ) from Invoice i",
 countQuery = "select count(*) from Invoice")
    Page<InvoiceQuery> getInvoicesByStatusAndName(Pageable pageable);

【讨论】:

  • 谢谢@Lucia。正如怀疑的那样,它看起来像是 Spring Data 中的一个错误 - 将在那里提交一个错误。我不知道提供 countQuery 的能力。谢谢你的信息。我的查询很大,有很多 where 子句,现在我必须在 countQuery 中重复这些子句。这样做会很痛苦,但至少我有一些东西。
猜你喜欢
  • 2018-12-12
  • 1970-01-01
  • 2021-09-23
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 2022-12-11
  • 2012-03-10
相关资源
最近更新 更多