简体   繁体   English

使用计数实现 JPA 投影

[英]Implement JPA Projection with count

I want to implement JPA Projection with count.我想用计数实现 JPA 投影。 I tried this:我试过这个:

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

But I get error: 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但我收到错误: 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 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

How I can implement proper count when I have class based Projection?当我有基于类的投影时,如何实现正确的计数?

Try Interface-based Projection instead of DTO:尝试基于接口的投影而不是 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);

Pay attention on aliases (ie id as id ) - they are mandatory.注意别名(即id as id )-它们是强制性的。

You are mixing JPQL and SQL syntax.您正在混合 JPQL 和 SQL 语法。

The constructor expression ( new ... ) is JPQL, but in the annotation you mark it as a nativeQuery ie as SQL so you have to make up your mind.构造函数表达式 ( new ... ) 是 JPQL,但在注释中,您将其标记为nativeQuery即 SQL,因此您必须下定决心。

If it is to be SQL I don't think you can use aliases in the ORDER BY clause, so you might have to either repeat the expression or wrap it in a subselect as described here: Using an Alias in a WHERE clause .如果是 SQL,我认为您不能在ORDER BY子句中使用别名,因此您可能必须重复表达式或将其包装在子选择中,如下所述: 在 WHERE 子句中使用别名

If it is to be JPQL it doesn't support aliases in a constructor expression, so I guess you have to repeat the expression in the order by clause.如果是 JPQL,它不支持构造函数表达式中的别名,所以我猜你必须在 order by 子句中重复表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM