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

Spring Boot JPA联表查询返回DTO部分字段为Null求助

问题原因及解决方案

你的问题核心是原生SQL查询结果与接口DTO的映射不匹配,导致Jackson序列化时部分字段返回null。虽然Spring Data JPA支持接口投影,但在原生查询场景下,接口方法与SQL列名的自动映射(驼峰转下划线)偶尔会出现失效,尤其是涉及关联查询和复杂类型时。

解决方案:改用类投影(Class Projection)

将原有的接口形式DTO改为带构造方法和Getter的静态内部类,Spring Data JPA会自动完成列名到属性的映射,Jackson序列化也更稳定。

1. 修改SchedulerAdminResponse类

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class SchedulerAdminResponse {

    private List<ScheduleDTO> scheduleDto;
    private CountProcessDTO countProcessDto;

    // 改为静态内部类,添加全参构造器和Getter
    @Getter
    @AllArgsConstructor
    public static class ScheduleDTO {
        private Long adminScheduleId;
        private String title;
        private String description;
        private Long userScheduleId;
        private String fullName;
        private Progress progress;
        private LocalDateTime scheduleStart;
    }

    @Getter
    @AllArgsConstructor
    public static class CountProcessDTO {
        private Integer waiting;
        private Integer accepted;
        private Integer refused;
    }
}

2. 调整Repository查询(无需修改SQL,保持原别名)

Spring Data JPA会自动将SQL中的下划线命名列(如admin_schedule_id)映射到类的驼峰命名属性(adminScheduleId),原Repository代码无需改动。

3. 可选:优化统计查询避免null值

如果某些状态没有数据,统计查询会返回null,可通过COALESCE函数将null转为0:

@Query(value =
        "SELECT COALESCE(SUM(T.WAITING), 0) AS waiting, COALESCE(SUM(T.ACCEPTED), 0) AS accepted, COALESCE(SUM(T.REFUSED), 0) AS refused " +
        "FROM (" +
        "   SELECT " +
        "   CASE WHEN progress = 'WAITING' THEN COUNT(progress) END AS WAITING, " +
        "   CASE WHEN progress = 'ACCEPT' THEN COUNT(progress) END AS ACCEPTED, " +
        "   CASE WHEN progress = 'REFUSE' THEN COUNT(progress) END AS REFUSED " +
        "   FROM scheduler_user_tb WHERE scheduler_admin_id = :id GROUP BY progress) AS T",
        nativeQuery = true)
SchedulerAdminResponse.CountProcessDTO countScheduleGroupByProgressById(Long id);

为什么接口投影会失效?

接口投影依赖Spring Data JPA动态生成代理类实现接口方法,在原生查询中,若列名与方法名的驼峰转换存在歧义(如关联表字段、枚举/日期类型),代理类可能无法正确绑定查询结果,导致序列化时返回null。类投影通过显式的属性和构造方法,避免了这种动态代理的不确定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:37:48