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

Spring JPA原生查询后无法获取数据列表,返回结果转Entrant类报错

错误原因

该报错是因为Spring Data JPA的原生查询默认没有内置转换器,无法直接将查询返回的TupleBackedMap结构自动映射到你自定义的非@EntityPOJO类Entrant上。

可用解决方法

方法1:使用JPA官方SqlResultSetMapping映射(兼容性最优)

这是JPA规范原生支持的映射方案,步骤如下:

  1. 在任意已有的@Entity实体类(如Event、User类都可以)上添加结果集映射注解:
@SqlResultSetMapping(
    name = "EntrantMapping",
    classes = @ConstructorResult(
        targetClass = Entrant.class,
        columns = {
            @ColumnResult(name = "firstname", type = String.class),
            @ColumnResult(name = "surname", type = String.class),
            @ColumnResult(name = "handicap", type = Double.class),
            @ColumnResult(name = "score", type = Integer.class)
        }
    )
)
@Entity
public class Event {
    // 原有Event实体的代码保持不变
}
  1. 修改Repository的@Query注解,指定刚才定义的映射:
@Query(value = "SELECT member.firstname, member.surname, member.handicap, entrants.score FROM member INNER JOIN entrants ON member.userid=entrants.member_id WHERE entrants.event_id=:eventid", 
       nativeQuery = true,
       resultSetMapping = "EntrantMapping")
List<Entrant> getEntrantDetails(long eventid);

方法2:使用接口投影(实现最简单)

如果不需要对返回的参赛人员信息做修改,可以直接把Entrant改成接口形式的投影,Spring Data会自动完成映射:

public interface EntrantProjection {
    String getFirstname();
    String getSurname();
    Double getHandicap();
    Integer getScore();
}

然后直接把Repository方法的返回值改成List<EntrantProjection>即可,不需要额外加其他注解。

方法3:手动转换结果集(灵活度最高)

先让Repository返回Map结构的结果集,在服务层手动转换为Entrant对象:

  1. 修改Repository方法:
@Query(value = "SELECT member.firstname, member.surname, member.handicap, entrants.score FROM member INNER JOIN entrants ON member.userid=entrants.member_id WHERE entrants.event_id=:eventid", nativeQuery = true)
List<Map<String, Object>> getEntrantDetails(long eventid);
  1. 修改服务层代码做类型转换:
public List<Entrant> getEntrantDetails(long id){
    List<Map<String, Object>> rawResult = eventRepository.getEntrantDetails(id);
    return rawResult.stream().map(item -> {
        Entrant entrant = new Entrant();
        entrant.setFirstname((String) item.get("firstname"));
        entrant.setSurname((String) item.get("surname"));
        entrant.setHandicap(((Number) item.get("handicap")).doubleValue());
        entrant.setScore((Integer) item.get("score"));
        return entrant;
    }).collect(Collectors.toList());
}

注意事项

  • 确保查询返回的字段名和Entrant类的字段名完全匹配,如有不一致可以在SQL中用AS别名调整
  • 注意字段类型匹配,数值类字段如果数据库返回为BigDecimal类型,需要先转为Number再转成对应类型避免类型转换异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:24:07