如何让MapStruct在else分支调用Collection.clear()方法
MapStruct集合映射代码自定义需求
MapStruct默认对集合映射时会生成如下代码:
if (entity.getCollection() != null) { Set<AnotherEntity> set = AnotherMapper.toEntities(request.getCollection()); if (set != null) { entity.getCollection().clear(); entity.getCollection().addAll(set); } else { entity.setCollection(null); } }
我希望修改配置,让MapStruct生成如下逻辑的代码:
if (entity.getCollection() != null) { Set<AnotherEntity> set = AnotherMapper.toEntities(request.getCollection()); if (set != null) { entity.getCollection().clear(); entity.getCollection().addAll(set); } else { entity.getCollection().clear(); } }
尝试过使用defaultExpression="java(entity.getCollection().clear())",但因clear()返回void不符合setter的返回值要求,无法正常工作。
解决方法
方法一:通过@AfterMapping自定义集合处理逻辑
在你的Mapper接口中,先忽略集合属性的自动映射,再通过@AfterMapping注解定义一个默认方法,手动实现你需要的集合更新逻辑:
@Mapper(uses = AnotherMapper.class) public interface EntityMapper { // 忽略集合属性的自动映射 @Mapping(target = "collection", ignore = true) void updateEntityFromRequest(Request request, @MappingTarget Entity entity); // 自定义集合处理逻辑 @AfterMapping default void handleCollectionUpdate(Request request, @MappingTarget Entity entity) { if (entity.getCollection() != null) { Set<AnotherEntity> set = AnotherMapper.toEntities(request.getCollection()); entity.getCollection().clear(); if (set != null) { entity.getCollection().addAll(set); } } } }
MapStruct生成代码时,会先完成其他属性的映射,再执行handleCollectionUpdate方法,完全按照你需要的逻辑处理集合。
方法二:修改集合转换方法的空值映射策略
如果允许将源集合转换后的null结果转为空集合,可以在AnotherMapper的集合转换方法上添加@IterableMapping注解,指定nullValueMappingStrategy为RETURN_EMPTY:
@Mapper public interface AnotherMapper { @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_EMPTY) Set<AnotherEntity> toEntities(Set<RequestItem> requestItems); }
这样当request.getCollection()为null时,toEntities会返回空集合而非null,MapStruct默认生成的代码会执行clear()后addAll空集合,最终效果和直接clear()一致。这种方法更简洁,但仅适用于可以接受空集合替代null的场景。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

