Spring Boot 3.2.5原生查询转换失败,JPQL正常的原因咨询
Spring Boot 3.2.5:原生SQL查询报类型转换错误,JPQL却正常的原因
错误栈追踪
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Integer] to type [com.train.management.entities.TrainDetails] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:294) ~[spring-core-6.1.6.jar:6.1.6] at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:185) ~[spring-core-6.1.6.jar:6.1.6] at org.springframework.core.convert.support.ArrayToObjectConverter.convert(ArrayToObjectConverter.java:68) ~[spring-core-6.1.6.jar:6.1.6] at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-6.1.6.jar:6.1.6] at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:182) ~[spring-core-6.1.6.jar:6.1.6] at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:165) ~[spring-core-6.1.6.jar:6.1.6] at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:305) ~[spring-data-commons-3.2.5.jar:3.2.5] at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:233) ~[spring-data-commons-3.2.5.jar:3.2.5] at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:240) ~[spring-data-commons-3.2.5.jar:3.2.5] at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:160) ~[spring-data-commons-3.2.5.jar:3.2.5] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:152) ~[spring-data-jpa-3.2.5.jar:3.2.5] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:137) ~[spring-data-jpa-3.2.5.jar:3.2.5]
相关代码
TrainDetails实体类
@Entity @Table(name = "train_details") public class TrainDetails { @Id @Column(name = "train_id") private String id; @Column(name = "train_name") private String trainName; @Column(name = "total_distance_covers") private String totalDistance; @Column(name = "train_code") private String trainCode; @Column(name = "total_stops") private int totalStops; @ManyToOne @JoinColumn(name = "start_station") private Station startStation; @ManyToOne @JoinColumn(name = "end_station") private Station endStation; @OneToMany(mappedBy = "trainName", cascade = CascadeType.ALL) private List<Coach> coaches; }
StationRepo仓库接口
报错的原生SQL查询
public interface StationRepo extends JpaRepository<Station, String> { // 原生SQL查询(报错) @Query(nativeQuery = true, value="SELECT td.*\r\n" + "FROM train_details td\r\n" + "JOIN station s_start ON td.start_station = s_start.station_id\r\n" + "JOIN station s_end ON td.end_station = s_end.station_id\r\n" + "WHERE s_start.station_code = ?1" + " OR s_end.station_code = ?1") public List<TrainDetails> getAllTrainsComingOnStation(String stationCode); }
正常工作的JPQL查询
public interface StationRepo extends JpaRepository<Station, String> { @Query("SELECT td FROM TrainDetails td\r\n" + "JOIN td.startStation s_start\r\n" + "JOIN td.endStation s_end\r\n" + "WHERE s_start.stationCode = :stationCode\r\n" + " OR s_end.stationCode = :stationCode\r\n") public List<TrainDetails> getAllTrainsComingOnStation(@Param("stationCode") String stationCode); }
原因解析
1. JPQL面向实体,自动处理关联映射
JPQL直接操作你定义的实体类和关联关系,JPA会自动解析td.startStation这类实体关联逻辑,查询结果会被完整映射为TrainDetails对象——即使关联的Station是懒加载,也会生成代理对象填充到对应属性中,不会出现类型不匹配问题。
2. 原生SQL仅返回数据库字段,无法自动处理实体关联
原生SQL是直接针对数据库表的查询,SELECT td.*只会返回train_details表的所有字段,其中start_station和end_station是存储外键值的字段(比如数字或字符串类型)。但你的TrainDetails类中这两个属性是Station类型的实体,Spring Data JPA不会自动把外键值转换为对应的Station实体,而是试图直接将外键值赋值给Station类型的属性,最终触发类型转换异常(栈追踪中显示的Integer转TrainDetails是转换链中的最终异常,本质是外键值无法转成Station实体)。
3. 原生SQL的可选解决方案
- 使用
@SqlResultSetMapping手动定义结果映射,将外键字段关联到Station实体; - 改用DTO类接收查询结果,避免返回包含关联实体的
TrainDetails; - 在原生SQL中查询关联表的字段,手动组装实体(不推荐,冗余且易出错)。
内容的提问来源于stack exchange,提问作者Rani
相关产品推荐
相关产品推荐

