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

SpringBoot SQL查询指定字段报错及修正查询正确性验证

问题分析与修正

原查询报错原因

原查询开启nativeQuery=true执行原生SQL,但返回类型是实体类Oas2ChannelPatient,而SQL仅查询了externalId和externalIdType两个字段。Spring Data JPA尝试将结果映射到实体类时,找不到channelPatientMapId等其他必填字段的对应值,因此抛出InvalidDataAccessResourceUsageException。

更新后的查询存在的问题

更新后的查询有多处错误,无法正常运行:

  • 语法冲突:NEW ChannelPatientSearchDto.ChannelExternalIdDTO(...)是JPQL专属的构造器语法,但同时设置了nativeQuery=true,原生SQL不支持这种写法。
  • 表/字段名不匹配:原数据库表为tb_patient_map,查询中却写了tb_oas_2_channel_patient_map;数据库字段是patientId,查询中误用了oasPatientId。
  • 参数绑定错误:方法参数标注@Param("patientId"),但查询中用:oasPatientId引用参数,名称不匹配导致参数无法绑定。
  • DTO类引用错误:用户定义的DTO是ChannelPatientDto.ChannelExternalIdDTO,查询中却引用了不存在的ChannelPatientSearchDto.ChannelExternalIdDTO。
  • 注解滥用:@Modifying仅用于更新/删除操作,查询语句不需要该注解。

正确的查询写法

方法一:JPQL+DTO构造器(推荐)

@Query(value = "SELECT NEW com.your.package.ChannelPatientDto.ChannelExternalIdDTO(t.externalId, t.externalIdType) " +
               "FROM tb_patient_map t " +
               "WHERE t.patientId = :patientId AND t.channelId = :channelId")
List<ChannelPatientDto.ChannelExternalIdDTO> findByPatientIdAndChannelId(@Param("patientId") String patientId, @Param("channelId") int channelId);

注意事项:

  1. 移除nativeQuery=true,使用JPQL语法;
  2. 替换com.your.package为DTO类实际所在的包路径;
  3. 表名、字段名严格与数据库结构保持一致;
  4. 查询操作无需@Modifying和@Transactional(特殊业务场景除外)。

方法二:原生SQL+接口投影(适合复杂查询场景)

若需保留原生SQL,可以定义投影接口:

public interface ChannelExternalIdProjection {
    String getExternalId();
    String getExternalIdType();
}

对应查询写法:

@Query(value = "SELECT externalId, externalIdType FROM tb_patient_map " +
               "WHERE patientId = :patientId AND channelId = :channelId", nativeQuery = true)
List<ChannelExternalIdProjection> findByPatientIdAndChannelId(@Param("patientId") String patientId, @Param("channelId") int channelId);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:57:40