【问题标题】:spring jpa @Query 错误,期待 CLOSE,发现 '('
【发布时间】:2022-01-23 16:53:52
【问题描述】:

我有一个运行良好的以下 mysql 查询:

*编辑:路径仅用于说明目的...我不想复制我的包...

select COUNT(IF(amount > 0, amount, 0)) as creditCount,
       COUNT(IF(amount < 0, amount, 0)) as debitCount,
       SUM(IF(amount > 0, amount, 0)) as credit,
       SUM(IF(amount < 0, amount, 0)) as debit,
       SUM(amount)                    as balance,
       cp.surname, cp.id, pcp.number from prepaid_card_transaction_pojo pctp
         join prepaid_card_pojo pcp on pctp.account = pcp.id
         join customer_pojo cp on pcp.id = cp.prepaid_card
where pcp.number = '1000765352' AND pctp.client = UUID_TO_BIN('fb9dbcac-cd03-46ad-94b0-2709b0b0e2a8') AND booking_time > '2020-12-01 00:00:00' group by cp.id;

我想转给jpql:

@Query("select new path...Bean(" + //
            "COUNT(IF(pctp.amount > 0, pctp.amount, 0))," + //
            "COUNT(IF(pctp.amount < 0, pctp.amount, 0)), " + //
            "SUM(IF(pctp.amount > 0, pctp.amount, 0)), " + //
            "SUM(IF(pctp.amount < 0, pctp.amount, 0)), " + //
            "SUM(pctp.amount), cp) " + //
            "FROM PrepaidCardTransactionPojo pctp " + //
            "JOIN PrepaidCardPojo pcp ON pctp.account = pcp.id " + //
            "JOIN CustomerPojo cp ON pcp.id = cp.prepaid_card " + //
            "WHERE pcp.number =:voucherNumber AND pctp.client =:client AND booking_time >= :from AND booking_time < :to GROUP BY :customer")
    List<Bean> loadGroupedCustomerPrepaidTransactions(@Param("client") ClientReadable client, @Param("customer") CustomerReadable customer, @Param("voucherNumber") String voucherNumber, @Param("from") Date from, @Param("to") Date to);

我收到以下错误: ...QuerySyntaxException: expecting CLOSE, found '(' near...

【问题讨论】:

  • 你认为这是正确的新路径吗...Bean(........
  • @RaushanKumar 我认为他写 Bean 是为了简单起见。

标签: java spring spring-data jpql


【解决方案1】:

感谢您的回答。经过几个小时的调整,以下是经验教训:

  • JPQL 不喜欢列别名...
  • JPQL 不喜欢 IF(正在使用 “COUNT(IF(pctp.amount > 0, pctp.amount, 0))”,应该使用: "COUNT(当 pctp.amount > 0 then 1 else 0 end),"
  • JPQL COUNT 应该使用数字作为匹配计数的次数 - 上面示例中的特定 1。而 mysql 只是将条件匹配值设为 1
  • 所有列出的属性都应该来自 pojo 指定而不是 DB 列指定,就像我在最初的帖子中所做的那样,以防 cp.prepaid_card

【讨论】:

    【解决方案2】:

    试着喜欢这个:

    @QUERY(nativeQuery = true, value = "select COUNT(IF(amount > 0, amount, 0)) as creditCount,
           COUNT(IF(amount < 0, amount, 0)) as debitCount,
           SUM(IF(amount > 0, amount, 0)) as credit,
           SUM(IF(amount < 0, amount, 0)) as debit,
           SUM(amount)                    as balance,
           cp.surname, cp.id, pcp.number from prepaid_card_transaction_pojo pctp
             join prepaid_card_pojo pcp on pctp.account = pcp.id
             join customer_pojo cp on pcp.id = cp.prepaid_card
    where pcp.number = :voucherNumber AND pctp.client = :client AND booking_time > :from AND booking_time < :to group by cp.id)
    List<Bean> loadGroupedCustomerPrepaidTransactions( ClientReadable client,  CustomerReadable customer,  String voucherNumber, Date from, Date to);
    

    【讨论】:

      【解决方案3】:

      尝试添加nativeQuery = true,表示查询是原生MySql查询,而不是Jpql查询。

      @Query("select ...", nativeQuery = true)
          List<Bean> loadGroupedCustomerPrepaidTransactions(...);
      

      【讨论】:

        【解决方案4】:

        我认为 JPQL 没有 if - 所以你必须使用 CASE WHEN ... ELSE ...,就像这样:

        SELECT e.name, CASE WHEN (e.salary &gt;= 100000) THEN 1 WHEN (e.salary &lt; 100000) THEN 2 ELSE 0 END from Employee e

        更多https://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF#New_in_JPA_2.0

        【讨论】:

          猜你喜欢
          • 2016-07-28
          • 2019-03-31
          • 1970-01-01
          • 2017-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-21
          • 2021-10-16
          相关资源
          最近更新 更多