Spring Boot中SQL查询报错‘Column id not found’求助
问题原因分析
你遇到的Column 'id' not found错误,核心原因是查询结果的字段和你要映射的OSColab实体不匹配:
- 你的原生SQL只返回了
colaborador_id和SUM(totalareceber)两个字段,但OSColab实体的主键是id,JPA在映射结果时,找不到对应的id列来填充实体的id属性,因此抛出该错误。
解决方案
针对聚合查询的结果,不能直接映射到完整的实体类,推荐用以下两种方式处理:
方式一:自定义DTO接收结果
创建一个只包含你需要字段的DTO类,用来接收聚合查询的返回值:
public class OSColabSumDTO { private Long colaboradorId; // 注意:这里的类型要和数据库中totalareceber的类型匹配,比如Integer/BigDecimal private BigDecimal totalRecebido; // 构造方法的参数顺序必须和SQL查询返回的列顺序完全一致 public OSColabSumDTO(Long colaboradorId, BigDecimal totalRecebido) { this.colaboradorId = colaboradorId; this.totalRecebido = totalRecebido; } // 添加getter和setter方法 public Long getColaboradorId() { return colaboradorId; } public void setColaboradorId(Long colaboradorId) { this.colaboradorId = colaboradorId; } public BigDecimal getTotalRecebido() { return totalRecebido; } public void setTotalRecebido(BigDecimal totalRecebido) { this.totalRecebido = totalRecebido; } }
然后修改Repository方法,返回这个DTO的列表:
public interface OSColabRepository extends JpaRepository<OSColab, Long> { @Query(value = "SELECT colaborador_id, SUM(totalareceber) FROM tb_oscolab INNER JOIN tb_os ON tb_oscolab.os_id = tb_os.id WHERE tb_os.data_inicio BETWEEN :startDate AND :endDate GROUP BY colaborador_id", nativeQuery = true) List<OSColabSumDTO> getOSColabSumBetweenDates(@Param("startDate") Date startDate, @Param("endDate") Date endDate); }
方式二:使用接口投影
创建一个投影接口,定义你需要获取的字段对应的getter方法:
public interface OSColabSumProjection { // 方法名要和SQL查询返回的列名对应,或者用@Value注解指定映射关系 Long getColaboradorId(); // 给SUM结果起别名,方便映射 BigDecimal getTotalRecebido(); // 如果列名和方法名不匹配,可以这样写: // @Value("#{target.colaborador_id}") // Long getColaboradorId(); // @Value("#{target.total_recebido}") // BigDecimal getTotalRecebido(); }
修改Repository方法,注意给聚合结果起别名:
public interface OSColabRepository extends JpaRepository<OSColab, Long> { @Query(value = "SELECT colaborador_id, SUM(totalareceber) AS total_recebido FROM tb_oscolab INNER JOIN tb_os ON tb_oscolab.os_id = tb_os.id WHERE tb_os.data_inicio BETWEEN :startDate AND :endDate GROUP BY colaborador_id", nativeQuery = true) List<OSColabSumProjection> getOSColabSumBetweenDates(@Param("startDate") Date startDate, @Param("endDate") Date endDate); }
不推荐的方式:返回完整实体
如果你强行要返回OSColab实体,需要在SQL中加入tb_oscolab.id,但这样会导致分组逻辑失效(因为每个id都是唯一的,分组后无法按colaborador_id汇总),所以不建议这么做。
内容的提问来源于stack exchange,提问作者Joao Ortega
相关产品推荐
相关产品推荐

