Spring Boot JPA查询指定列时报ResultSet未找到id列错误如何解决?
报错根因
你定义的原生SQL仅返回了name、image两个字段,但Repository方法的返回值是Page<CharacterEntity>,Hibernate在映射结果到实体类时,必须读取主键字段id才能完成实体封装,因此抛出找不到id列的异常。
解决方案
你可以根据自己的业务需求选择以下任意一种方案:
方案1:补充查询id字段,直接返回实体(改造成本最低)
如果可以接受同时查询id字段,仅需要修改Repository的查询SQL,加入id列即可:
public interface CharacterRepository extends JpaRepository<CharacterEntity, Long> { // 补充id字段到查询列中 @Query(value = "SELECT id, name, image FROM characters", countQuery = "SELECT COUNT(name) FROM characters", nativeQuery = true) Page<CharacterEntity> getCharacters(Pageable pageable); }
该方案返回的CharacterEntity实体中,除id、name、image外的其余字段均为null,业务侧直接按需读取对应字段即可。
方案2:DTO投影(推荐,类型安全)
如果不想返回带空字段的实体,要直接返回仅包含指定字段的DTO,分两种实现场景:
2.1 JPQL+构造器表达式(非必须用原生SQL首选)
首先给CharacterDto新增对应字段的构造方法:
// 新增到CharacterDto类中 public CharacterDto(long id, String image, String name) { this.id = id; this.image = image; this.name = name; }
修改Repository方法,使用JPQL构造器注入:
public interface CharacterRepository extends JpaRepository<CharacterEntity, Long> { // 注意替换为你实际的CharacterDto全类名 @Query(value = "SELECT new com.xxx.xxx.CharacterDto(c.id, c.image, c.name) FROM characters c", countQuery = "SELECT COUNT(c.id) FROM characters c") Page<CharacterDto> getCharacters(Pageable pageable); }
2.2 原生SQL+结果集映射(必须用原生SQL场景)
先在CharacterEntity类上配置结果集映射:
@Entity(name = "characters") @Getter @Setter // 新增结果集映射配置 @SqlResultSetMapping( name = "CharacterDtoMapping", classes = @ConstructorResult( targetClass = com.xxx.xxx.CharacterDto.class, // 替换为实际的DTO全类名 columns = { @ColumnResult(name = "id", type = Long.class), @ColumnResult(name = "image", type = String.class), @ColumnResult(name = "name", type = String.class) } ) ) public class CharacterEntity implements Serializable { // 原有代码保持不变 }
修改Repository方法指定映射规则:
public interface CharacterRepository extends JpaRepository<CharacterEntity, Long> { @Query(value = "SELECT id, name, image FROM characters", countQuery = "SELECT COUNT(name) FROM characters", nativeQuery = true, resultSetMapping = "CharacterDtoMapping") // 对应上面配置的映射名 Page<CharacterDto> getCharacters(Pageable pageable); }
方案3:接口投影(轻量无额外配置)
定义一个仅包含所需字段get方法的接口:
public interface CharacterProjection { Long getId(); String getName(); String getImage(); }
Repository方法直接返回该接口类型的分页即可,JPQL和原生SQL均支持:
// 原生SQL版本 @Query(value = "SELECT id, name, image FROM characters", countQuery = "SELECT COUNT(name) FROM characters", nativeQuery = true) Page<CharacterProjection> getCharacters(Pageable pageable);
业务侧直接调用接口的get方法即可读取对应字段值。
内容的提问来源于stack exchange,提问作者Lombardinho
相关产品推荐
相关产品推荐

