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

Spring Data JPA无法将JSON类型映射到DTO的问题求助

问题解决步骤

1. 修复实体类名与SQL关键字冲突

Group是SQL保留关键字,直接在JPQL中使用FROM Group g会触发语法解析异常,进而导致构造函数匹配失败。修改实体类的映射名称:

@Entity(name = "groups") // 指定JPQL中使用的实体别名
public class Group {
  @Id
  private long id;
  @Column
  private String uuid;
  @Column
  @Type(JsonType.class) 
  private Info info;
}

对应的JPQL查询同步修改:

@Query(value = "SELECT new com.example.InfoDto(g.uuid, g.info) FROM groups g")
List<InfoDto> findInfoDto();

2. 确保DTO构造参数与JPQL查询完全匹配

针对Record类型的InfoDto

Spring Data JPA 2.4+原生支持Record作为DTO,只需保证Record的参数顺序、类型与JPQLnew语句的参数完全一致:

public record InfoDto(String uuid, Info info) {}

同时要确认@Type(JsonType.class)能正确将数据库JSON列转换为Info对象——如果使用Hibernate,可替换为官方JSON类型简化映射:

import org.hibernate.annotations.JdbcTypeCode;
import java.sql.Types;

@Column
@JdbcTypeCode(Types.JSON)
private Info info;

针对普通类的InfoDto

必须提供public权限、参数顺序/类型与JPQL完全匹配的构造函数:

public class InfoDto {
    private String uuid;
    private Info info;

    // 构造函数必须为public,参数顺序和类型严格对应JPQL中的new语句
    public InfoDto(String uuid, Info info) {
        this.uuid = uuid;
        this.info = info;
    }

    // 可选:添加getter方法供后续逻辑使用
    public String getUuid() { return uuid; }
    public Info getInfo() { return info; }
}

3. 备选方案:使用接口投影

如果上述方法仍有问题,可改用基于接口的投影替代手动DTO构造:

public interface InfoDtoProjection {
    String getUuid();
    Info getInfo();
}

修改查询方法:

@Query(value = "SELECT g.uuid, g.info FROM groups g")
List<InfoDtoProjection> findInfoDto();

Spring Data JPA会自动生成代理类实现该接口,无需手动定义实体类或Record。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:06:16