SpringBoot JPA执行update报Not supported for DML operations错误
问题根因
- 直接触发异常的原因:Spring Data JPA 中被
@Modifying标记的update/delete类DML操作,仅支持返回void、int、Integer类型(对应当次操作影响的数据库行数),不支持返回实体集合。你当前Repository方法定义返回List<Employee>,框架会默认按普通查询逻辑执行,自然无法处理DML语句,直接抛出Not supported for DML operations异常。 - 代码里还存在几个会引发后续问题的隐患:
- 批量更新操作未配置事务,执行时会报事务Required错误
- Service层方法入参顺序和Controller传参、Repository方法的参数顺序不匹配,就算不报错也会把部门、办公室的值传反,更新错数据
- 更新操作使用GET请求不符合接口语义,GET规范上仅用于无副作用的查询操作
@Modifying未配置缓存自动清理,更新后直接查询可能拿到JPA持久化上下文里的旧缓存数据,返回结果和数据库实际值不一致
修复方案
1. 调整Repository层代码
把DML方法的返回值改为int,配置自动刷新、清理持久化上下文,补充按部门查询员工的方法:
// 批量更新办公室的DML方法 @Modifying(clearAutomatically = true, flushAutomatically = true) @Query("update Employee u set u.office = :office where u.department = :department") int assignOffice (@Param("office") String office, @Param("department") String department); // 新增按部门查询员工列表的方法,更新后重新查询返回最新数据 List<Employee> findByDepartment(String department);
*事务注解建议加在Service层的业务方法上,更符合分层设计规范。
2. 调整ServiceImpl层代码
修正参数顺序,加上事务注解,执行完更新后重新查询对应部门的员工列表返回:
@Override @Transactional(rollbackFor = Exception.class) public List<Employee> assignOffice(String office, String department) { // 执行批量更新,返回值为受影响的员工数量 employeeRepository.assignOffice(office, department); // 重新查询该部门最新的员工列表返回 return employeeRepository.findByDepartment(department); }
3. 调整Controller层代码
把GET请求改为PUT请求(修改类操作对应PUT语义),对齐参数顺序:
@PutMapping(path="/assign") public ResponseEntity<List<Employee>> assignOffice(@RequestParam("office") String office, @RequestParam("department") String department){ return ResponseEntity.ok(employeeService.assignOffice(office, department)); }
内容的提问来源于stack exchange,提问作者NewDeveloper
相关产品推荐
相关产品推荐

