You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot JPA执行select查询报错与日期比较问题排查

问题场景

需要查询入职日期晚于指定日期、薪资高于指定阈值的员工数据,传入参数为startdate=2000-10-22、salary=10000时,执行查询抛出如下异常:

"org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for select queries [Select e FROM com.example.macademiaproject.model.Employee e  where  (:startDate is NULL or e.startDate < :startDate)  AND  (:salary is NULL or e.salary > :salary) ]; nested exception is java.lang.IllegalStateException: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for select queries [Select e FROM com.example.macademiaproject.model.Employee e  where  (:startDate is NULL or e.startDate < :startDate)  AND  (:salary is NULL or e.salary > :salary) ]",

现有两点疑问:

  • 是否可以直接使用>、<这类比较符判断日期先后,例如判断2000/12/13 > 2001/5/8是否成立?如果不支持该如何正确实现日期比较?
  • 上述报错的产生原因是什么,该如何修复?
项目各层相关代码

Repository层代码

@Transactional
@Modifying
@Query("Select e FROM Employee e  " +
        "where " +
        " (:startDate is NULL or e.startDate < :startDate) " +
        " AND " +
        " (:salary is NULL or e.salary > :salary) ")
void searchEmployees(@Param(value= "startDate")Date startDate,@Param(value = "salary") Integer salary);

Service层接口代码

void searchEmployees(Date startDate,Integer salary);

Service实现类代码

@Override
public void searchEmployees(Date startDate,Integer salary){
   employeeRepository.searchEmployees(startDate,salary);
}

Controller层代码

@GetMapping(path="/search")
public ResponseEntity<List<Employee>> searchEmployees(@RequestParam("startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date startDate,
                                                      @RequestParam("salary") Integer salary) {
    employeeService.searchEmployees(startDate,salary);
    return null; 
}
问题解答

关于HQL日期比较的说明

只要实体类的日期字段、传入的查询参数都是标准日期类型(包括java.util.Date、java.sql.Date、JDK8+的LocalDate/LocalDateTime等),可以直接使用>、<、>=、<=比较符判断日期先后,Hibernate会自动完成类型适配,不需要额外写函数转换。
如果传入的是未做类型转换的日期字符串,不能直接用比较符判断:字符串会按照字典序逐字符比较,比如"2000/12/13"和"2000/5/8"比较时,逐字符匹配到月份位置,字符'1'的ASCII码小于'5',会判定前者更小,但实际12月晚于5月,结果完全不符合日期逻辑。这种情况需要先把字符串解析为日期类型,再做比较。
另外注意你的业务需求是查询入职日期晚于指定日期,对应的比较逻辑应该是e.startDate > :startDate,现有代码写的是<,逻辑本身是反的。

报错原因与修复方案

核心报错原因

Repository方法上错误使用了@Modifying注解:这个注解仅支持标记增删改类的DML操作(INSERT/UPDATE/DELETE),你的查询是SELECT类型的查询操作,Hibernate检测到修改操作的执行逻辑遇到SELECT语句,就会抛出Not supported for select queries异常。
除了核心报错外,现有代码还存在几个逻辑问题:

  • Repository方法返回值定义为void,无法返回查询到的员工列表结果
  • 日期比较条件写反,和业务需求不匹配
  • Service层、Controller层没有透传查询结果,Controller直接返回null,前端拿不到数据
  • Controller层的查询参数默认是必传,和你写的参数为NULL则不触发条件过滤的逻辑不匹配,不传参数会直接报400错误

修复步骤

  1. 移除Repository方法上的@Modifying注解,只读查询不需要该注解,如需加事务可配置@Transactional(readOnly = true)提升性能
  2. 将Repository、Service层的searchEmployees方法返回值从void修改为List<Employee>
  3. 修正HQL中的日期比较条件,将e.startDate < :startDate改为e.startDate > :startDate,匹配"入职日期晚于指定日期"的需求
  4. 补全各层的结果透传逻辑,Controller将查询到的列表封装到响应中返回,同时给请求参数加上required = false支持非必传

修复后的各层代码参考如下:

修复后Repository代码

@Query("Select e FROM Employee e  " +
        "where " +
        " (:startDate is NULL or e.startDate > :startDate) " +
        " AND " +
        " (:salary is NULL or e.salary > :salary) ")
List<Employee> searchEmployees(@Param(value= "startDate")Date startDate,@Param(value = "salary") Integer salary);

修复后Service接口代码

List<Employee> searchEmployees(Date startDate,Integer salary);

修复后Service实现类代码

@Override
public List<Employee> searchEmployees(Date startDate,Integer salary){
   return employeeRepository.searchEmployees(startDate,salary);
}

修复后Controller代码

@GetMapping(path="/search")
public ResponseEntity<List<Employee>> searchEmployees(
        @RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date startDate,
        @RequestParam(value = "salary", required = false) Integer salary) {
    List<Employee> employeeList = employeeService.searchEmployees(startDate,salary);
    return ResponseEntity.ok(employeeList);
}

内容的提问来源于stack exchange,提问作者RohanRider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:06:32