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

Spring ConverterNotFoundException:Asset无法转换为AssetPageView

问题描述

报错信息:

org.springframework.core.convert.ConverterNotFoundException: 未找到能够将类型[com.skywarelabs.runwayreporting.api.modules.asset.Asset]转换为类型[com.skywarelabs.runwayreporting.api.modules.asset.AssetPageView]的转换器

存在两个Repository方法,预期均返回Page<T>对象。调用findPageByAerodrome可正常运行,但调用findPageByFilter时触发上述错误,需要使用findPageByFilter以扩展更多过滤参数。

Repository代码:

public interface AssetRepository extends PageCrudRepository<Asset, Long> {

    @Query("SELECT a FROM Asset a WHERE " +
            "(a.aerodrome = :aerodrome)")
    <T> Page<T> findPageByFilter(@Param("aerodrome") Aerodrome aerodrome,
                                 Pageable pageable, Class<T> type);

    <T> Page<T> findPageByAerodrome(@Param("aerodrome") Aerodrome aerodrome,
                                    Pageable pageable, Class<T> type);
}
原因及解决方案

原因分析

Spring Data JPA的自动生成查询方法(如findPageByAerodrome)会自动处理实体到DTO的转换逻辑,但带@Query注解的自定义查询方法不会触发该自动转换,因此直接返回的Asset实体无法被转换为AssetPageView。

解决方法

  1. 自定义查询直接构造DTO
    在@Query中调用AssetPageView的构造函数,直接返回目标类型,避免后续转换:

    @Query("SELECT new com.skywarelabs.runwayreporting.api.modules.asset.AssetPageView(a.id, a.name, ...) " +
           "FROM Asset a WHERE a.aerodrome = :aerodrome")
    <T> Page<T> findPageByFilter(@Param("aerodrome") Aerodrome aerodrome,
                                 Pageable pageable, Class<T> type);
    

    注意:需确保AssetPageView存在对应参数的构造函数,参数顺序要与查询中选取的字段一致。

  2. 注册全局类型转换器
    创建转换器类并注册到Spring容器,让框架自动完成实体到DTO的转换:

    @Component
    public class AssetToAssetPageViewConverter implements Converter<Asset, AssetPageView> {
        @Override
        public AssetPageView convert(Asset source) {
            AssetPageView view = new AssetPageView();
            // 手动映射字段,例如 view.setId(source.getId());
            return view;
        }
    }
    

    此方式适合需要全局复用转换逻辑的场景,自定义查询只需返回Asset实体,由Spring后续自动转换。

  3. 使用Spring Data投影接口
    若AssetPageView是接口形式的投影,可直接修改方法返回类型,无需传递Class<T>参数:

    @Query("SELECT a FROM Asset a WHERE a.aerodrome = :aerodrome")
    Page<AssetPageView> findPageByFilter(@Param("aerodrome") Aerodrome aerodrome, Pageable pageable);
    

    前提是AssetPageView接口的方法名与Asset实体的字段getter方法对应,Spring会自动处理投影转换。

内容的提问来源于stack exchange,提问作者Werner Reiche

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:39:36