使用Spring @Query运行JPQL查询时遇到异常

时间:2016-09-17 07:14:56

标签: java hibernate jpa spring-data-jpa

@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.

1 个答案:

答案 0 :(得分:0)

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)")