【问题标题】:Got an exception while running a JPQL query using Spring @Query使用 Spring @Query 运行 JPQL 查询时出现异常
【发布时间】:2016-09-17 07:14:56
【问题描述】:
@Query("select new map(count(t.status) as allCount,sum(case when t.status='Approved' then 1 else 0 end) as approvedCount, "
        + "sum(case when t.status='Overdue'  then 1 else 0 end) as overdueCount,"
        + "sum(case when t.status='Rejected' then 1 else 0 end) as rejectedCount,"
        + "sum(case when t.status='Awaiting Approval' then 1 else 0 end) as awaitingApprovalCount,"
        + "sum(case when t.status='Not Submitted' then 1 else 0 end) as notSubmittedCount) "
        + "from Timesheet as t where t.emplId=:employeeId and (t.startDate between date_add(:startDate, interval -6 day) and date_add(:endDate,interval 6 day))"
        + "and (t.endDate between date_add(:startDate, interval -6 day) and date_add(:endDate,interval 6 day))")

它抛出异常的地方为org.hibernate.hql.internal.ast.QuerySyntaxException : Expecting CLOSE, found 'day' near line 1.

【问题讨论】:

  • 任何 JPQL 参考资料都会告诉您...“date_add”、“interval”、“day”是无效的 JPQL 关键字。 JPQL != SQL

标签: java hibernate jpa spring-data-jpa


【解决方案1】:

JPA 不理解这个 MySQL 函数。 因此,要解决您的问题,您应该在查询之外计算间隔,并将间隔作为参数提供给查询。
在您的情况下,您应该设法做到这一点,因为间隔不依赖于请求表中的任何数据,而是依赖于执行查询之前的已知数据,因为您使用 :startDate:endDate 参数计算间隔:

 and (t.startDate between date_add(:startDate, interval -6 day)
 and date_add(:endDate,interval 6 day))+
 and (t.endDate between date_add(:startDate, interval -6 day) and  
 date_add(:endDate,interval 6 day))")

在调用查询的方法中,计算日期(我使用 JodaTime 作为示例):

Date computedStartDate = new DateTime(startdate).minusDay(6).toDate();
Date computedEndDate = new DateTime(endDate).plusDay(6).toDate();
...
// you create your query
//...
//you set these dates
 query.setParameter("computedStartDate",computedStartDate);
 query.setParameter("computedEndDate",computedEndDate);
// you execute your query

在查询中,您将 MySql 函数替换为这些参数化日期。

@Query("select new map(count(t.status) as allCount,sum(case when t.status='Approved' then 1 else 0 end) as approvedCount, "
        + "sum(case when t.status='Overdue'  then 1 else 0 end) as overdueCount,"
        + "sum(case when t.status='Rejected' then 1 else 0 end) as rejectedCount,"
        + "sum(case when t.status='Awaiting Approval' then 1 else 0 end) as awaitingApprovalCount,"
        + "sum(case when t.status='Not Submitted' then 1 else 0 end) as notSubmittedCount) "
        + "from Timesheet as t where t.emplId=:employeeId and (t.startDate between :computedStartDate and :computedEndDate)"
        + "and (t.endDate between :computedStartDate and :computedEndDate)")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 2011-05-11
    • 2019-03-09
    相关资源
    最近更新 更多