如何跨项目转换同结构不同包的PagedDataAndSortDto对象?
解决Mapstruct泛型映射不同包同结构DTO的问题
错误原因
你遇到的Can't generate mapping method for a generic type variable source错误,核心原因是Mapstruct需要在编译期确定具体的源和目标类型才能生成映射代码,而泛型类型变量<T,S>在编译阶段会被类型擦除,Mapstruct无法识别实际要映射的类结构,因此无法生成对应的实现逻辑。
可行解决方案
方案1:编写具体类型的Mapper(最直接)
因为两个DTO结构完全一致、字段名完全匹配,直接定义针对具体类型的Mapper即可,Mapstruct会自动完成字段映射,甚至不需要手动写@Mapping:
@Mapper(componentModel = "spring") public interface PagedDataAndSortDtoMapper { en.utilities.dto.PagedDataAndSortDto convert(en.testmodule.utils.gestionmoduleone.model.PagedDataAndSortDto source); }
使用时直接注入这个Mapper调用convert方法即可完成转换。
方案2:泛型基类+具体子Mapper(适配多同结构DTO场景)
如果有多个类似的同结构不同包的DTO需要转换,可以先定义一个泛型基类,再针对每个具体类型实现子Mapper:
// 泛型基类,仅定义映射方法模板 public abstract class BasePagedDataMapper<T, S> { public abstract T map(S source); } // 针对具体类型的子Mapper,Mapstruct会自动生成实现 @Mapper(componentModel = "spring") public interface TestToUtilityPagedMapper extends BasePagedDataMapper<en.utilities.dto.PagedDataAndSortDto, en.testmodule.utils.gestionmoduleone.model.PagedDataAndSortDto> { }
这种方式既复用了泛型的结构,又给Mapstruct提供了具体的类型信息用于生成代码。
方案3:利用Mapstruct的@MapperConfig复用配置(可选)
如果需要统一配置映射规则(比如忽略某些字段、自定义类型转换),可以用@MapperConfig定义公共配置,再在具体Mapper中引用:
@MapperConfig(componentModel = "spring") public interface PagedMapperConfig { // 这里可以定义公共的映射规则,比如忽略某个字段 } @Mapper(config = PagedMapperConfig.class) public interface PagedDataAndSortDtoMapper { en.utilities.dto.PagedDataAndSortDto convert(en.testmodule.utils.gestionmoduleone.model.PagedDataAndSortDto source); }
额外提示
如果DTO字段名完全一致,Mapstruct会自动完成映射,不需要手动添加@Mapping注解;如果有字段名不一致的情况,再针对性添加@Mapping(target = "xxx", source = "yyy")即可。
内容的提问来源于stack exchange,提问作者Paco Pinazo Guna
相关产品推荐
相关产品推荐

