Spring Data JPA原生查询遇ConverterNotFoundException问题求助
解决Spring Data JPA原生查询的类型转换异常
问题场景
我编写了如下Spring Data JPA原生查询方法:
@Query(value = "SELECT t1.* FROM western_en AS t1 " + "JOIN (SELECT id FROM western_en " + "ORDER BY RAND() LIMIT 10) as t2 ON t1.id=t2.id", nativeQuery = true) List<WesternEs> findRandom();
运行该查询时出现类型转换异常:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Long] to type [com.models.WesternEs] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:294) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:185) at org.springframework.core.convert.support.ArrayToObjectConverter.convert(ArrayToObjectConverter.java:68) at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
实体类定义如下:
@Entity @Table(name = "t_western_es") @Getter @Setter @AllArgsConstructor @NoArgsConstructor @Builder @ToString @Slf4j public class WesternEs implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; ... }
问题根源
实体类通过@Table注解映射的表是t_western_es,但原生查询语句中使用的表名是western_en,两者不匹配。数据库返回的结果结构无法和WesternEs实体类对应,Spring Data JPA无法完成对象映射,因此抛出类型转换异常。
解决方法
- 修正表名匹配问题:将查询语句中的
western_en替换为实体类对应的表名t_western_es,修改后的代码如下:
@Query(value = "SELECT t1.* FROM t_western_es AS t1 " + "JOIN (SELECT id FROM t_western_es " + "ORDER BY RAND() LIMIT 10) as t2 ON t1.id=t2.id", nativeQuery = true) List<WesternEs> findRandom();
- 检查表名一致性:确保数据库实际表名、
@Table注解的name属性值、原生查询中的表名三者完全一致,注意数据库是否区分大小写(比如PostgreSQL默认区分,MySQL默认不区分)。 - 性能优化(可选):如果数据库数据量较大,
ORDER BY RAND()的性能会很差,可以改用更高效的随机查询方式,比如先随机生成主键范围再查询(仅适用于自增主键):
@Query(value = "SELECT * FROM t_western_es WHERE id >= (SELECT FLOOR(RAND()*(SELECT MAX(id) FROM t_western_es))) LIMIT 10", nativeQuery = true) List<WesternEs> findRandom();
内容的提问来源于stack exchange,提问作者Nunyet Calçada
相关产品推荐
相关产品推荐

