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

为什么JPA原生查询返回对象仅能拿到值没有对应字段键

问题原因

你当前接口返回仅含值无字段键的核心原因是:你在Repository层的原生查询定义的返回类型为List<Object[]>,JPA处理该类返回值时只会按SQL中select字段的顺序存储对应值,不会自动绑定字段名做映射,Spring MVC序列化该数组结构时自然只会输出纯值序列,没有字段键。

解决方法

方法1:用Map类型接收结果(快速实现无需新建类)

直接将Repository、Dao、Controller三层的返回值类型从List<Object[]>全量替换为List<Map<String, Object>>即可。
修改示例:

// Repository层修改
@Query(value = "select distinct u.first_name, u.last_name, u.full_name, u.id from public.user u inner join public.users_group ug on u.id = ug.user_id and ug.group_list_id=1 WHERE status=1 ORDER BY u.id DESC", nativeQuery = true)
List<Map<String, Object>> getAllInstructors();

JPA会自动把查询字段名作为Map的key,对应值作为Map的value,序列化后就是你需要的键值对结构。

方法2:自定义DTO/投影接口接收(生产环境更推荐,类型安全)

方式A:接口投影(实现最简单)

定义和查询字段匹配的投影接口:

public interface InstructorProjection {
    // getter方法名和数据库字段驼峰对应,first_name对应getFirstName()
    String getFirstName();
    String getLastName();
    String getFullName();
    Long getId();
}

将各层返回类型改为List<InstructorProjection>即可,Spring Data JPA会自动完成字段映射。

方式B:实体DTO类

定义带全参构造的DTO类:

public class InstructorDTO {
    private String firstName;
    private String lastName;
    private String fullName;
    private Long id;

    // 构造参数顺序要和SQL select字段顺序完全一致
    public InstructorDTO(String firstName, String lastName, String fullName, Long id) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.fullName = fullName;
        this.id = id;
    }
    // 补全所有字段的getter、setter方法
}

如果是JPQL查询可以直接在select语句中new该DTO,原生SQL则搭配@SqlResultSetMapping注解完成映射即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:39:01