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

Spring Data JPA原生查询映射自定义DTO报No converter found错误如何处理

错误产生原因
  • Spring Data JPA 原生查询默认返回TupleBackedMap(元组映射的Map结构)或Object[]类型的结果集,你定义的UsersXCountry是普通POJO类,没有配置对应的字段映射规则,JPA没有内置转换器可以直接把查询结果自动映射到自定义普通类实例。
  • 你的原生查询返回的列没有匹配DTO属性名:查询返回的列分别是无别名的count('1')、下划线命名的country_code,和DTO中驼峰命名的numUsers、countryCode属性无法自动对应,进一步导致映射失败。
解决方案

下面是3种常用的可行方案:

方案1:使用接口投影(最简方案)

把UsersXCountry改为接口形式定义投影,JPA会自动生成代理类完成映射:

// 改为接口,定义和返回字段对应的getter方法
public interface UsersXCountry {
    Integer getNumUsers();
    String getCountryCode();
}

修改Repository中的查询语句,给查询列加和getter对应的别名:

@Query(value = "select count('1') as numUsers, country_code as countryCode from t_user group by country_code",nativeQuery = true)
List<UsersXCountry> usersXCountry();

方案2:使用结果集映射注解适配POJO

如果要保留UsersXCountry作为普通类的写法,先给类加全参构造方法:

public class UsersXCountry {
    Integer numUsers;
    String countryCode;
    // 手动加或者用Lombok的@AllArgsConstructor生成
    public UsersXCountry(Integer numUsers, String countryCode) {
        this.numUsers = numUsers;
        this.countryCode = countryCode;
    }
    // 按需加getter、setter
}

在项目任意被JPA扫描的实体类上或者当前DTO类上添加结果集映射配置:

@SqlResultSetMapping(
    name = "UsersXCountryMapping",
    classes = @ConstructorResult(
        targetClass = UsersXCountry.class,
        columns = {
            @ColumnResult(name = "numUsers", type = Integer.class),
            @ColumnResult(name = "countryCode", type = String.class)
        }
    )
)

修改Repository的查询注解,指定映射规则,同时给查询列加别名:

@Query(value = "select count('1') as numUsers, country_code as countryCode from t_user group by country_code",
       nativeQuery = true,
       resultSetMapping = "UsersXCountryMapping")
List<UsersXCountry> usersXCountry();

方案3:手动转换结果集

无需修改查询和DTO配置,先接收原始结果集再手动转换:

// Repository层先返回原始Object数组
@Query(value = "select count('1'), country_code from t_user group by country_code",nativeQuery = true)
List<Object[]> usersXCountryRaw();

在业务层手动转换:

List<Object[]> rawList = userRepository.usersXCountryRaw();
List<UsersXCountry> result = rawList.stream().map(arr -> 
    new UsersXCountry(((Number)arr[0]).intValue(), (String)arr[1])
).toList();

内容的提问来源于stack exchange,提问作者Nunyet Calçada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:18:02