【问题标题】:Implement JPA Projection with count使用计数实现 JPA 投影
【发布时间】:2019-11-30 12:24:54
【问题描述】:

我想用计数来实现 JPA 投影。我试过这个:

@Query(value = "SELECT new org.service.PaymentTransactionsDeclineReasonsDTO( id, count(id) as count, status, error_class, error_message) " +
        " FROM payment_transactions " +
        " WHERE terminal_id = :id AND (created_at > :created_at) " +
        " AND (status != 'approved') " +
        " GROUP BY error_message " +
        " ORDER BY count DESC", nativeQuery = true)
List<PaymentTransactionsDeclineReasonsDTO> transaction_decline_reasons(@Param("id") Integer transaction_unique_id, @Param("created_at") LocalDateTime created_at);

但我收到错误:Caused by: java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.plugin.service.PaymentTransactionsDeclineReasonsDTO( id, count(id) as c' at line 1

当我有基于类的投影时如何实现正确的计数?

【问题讨论】:

  • 删除 =: 之间的空格,如下WHERE terminal_id =:id AND (created_at &gt;:created_at) " +
  • 你确定吗?错误在于第 1 行的 count(id) as c'?
  • 一旦我遇到类似的错误并通过这样做解决了,你可以试试。也删除 > & 之间的空格:

标签: java jpa spring-data-jpa jpa-2.0


【解决方案1】:

尝试Interface-based Projection 而不是 DTO:

public interface TransactionDeclineReason {
   Integer getId();
   Long getCount();
   Status getStatus();
   ErrorClass getErrorClass(); // I suppose it's enum...
   String getErrorMessage();
}
@Query(value = "select " +
                 "id as id, " + 
                 "count(id) as count, " + 
                 "status as status, " + 
                 "error_class as errorClass, " + 
                 "error_message as errorMessage " +
               "from " +
                 "payment_transactions " +
               "where " +
                 "terminal_id = ?1 " + 
                 "and created_at > ?2 " +
                 "and status != 'approved' " +
               "group " + 
                 "by error_message " +
               "order by " +
                 "2 desc", nativeQuery = true)
List<TransactionDeclineReason> getTransactionDeclineReasons(Integer transactionId, LocalDateTime createdAt);

注意别名(即id as id) - 它们是强制性的。

【讨论】:

    【解决方案2】:

    您正在混合使用 JPQL 和 SQL 语法。

    构造函数表达式 (new ...) 是 JPQL,但在注释中您将其标记为 nativeQuery,即 SQL,因此您必须下定决心。

    如果是 SQL,我认为您不能在 ORDER BY 子句中使用别名,因此您可能必须重复表达式或将其包装在子选择中,如下所述:Using an Alias in a WHERE clause

    如果是 JPQL,它不支持构造函数表达式中的别名,所以我想你必须在 order by 子句中重复表达式。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 2012-04-05
    • 2015-02-06
    • 1970-01-01
    • 2018-11-25
    • 2019-02-08
    • 1970-01-01
    相关资源
    最近更新 更多