如何在Mapstruct集合映射器中使用装饰方法?

时间:2016-05-16 11:04:24

标签: java decorator mapstruct

我在使用依赖注入的Spring应用程序中使用MapStruct从JPA实体映射到POJO DTO。

我已将DTO的一些额外处理添加到装饰器as specified in the doc中的方法。

它适用于映射单个实体。但我也有这些实体的集合(集合)的映射,当在关系中找到这些实体的集合时,会自动调用该方法。

但是生成的集合映射方法不使用装饰方法来映射每个实体,只是在委托上使用“vanilla”生成的方法。以下是生成方法的代码:

@Override
public Set<DimensionItemTreeDTO> missionSetToTreeDtoSet(Set<Mission> set)  {
    return delegate.missionSetToTreeDtoSet( set );
}

委托方法本身不知道装饰器并且自己调用单个项目映射方法:

@Override
public Set<DimensionItemTreeDTO> missionSetToTreeDtoSet(Set<Mission> set) {
    if ( set == null ) {
        return null;
    }

    Set<DimensionItemTreeDTO> set__ = new HashSet<DimensionItemTreeDTO>();
    for ( Mission mission : set ) {
        set__.add( missionToTreeDto( mission ) ); //here the decorator is not called !
    }

    return set__;
}

...并且永远不会为集合中的项目调用装饰方法。

有没有一种方法可以让Mapstruct在集合映射中使用装饰器方法,而不是在我的装饰器中手动编写集合方法(它工作但是很冗长,并且在第一个地方没有使用MapStruct的目的必须写这种代码)?

1 个答案:

答案 0 :(得分:6)

我找到了问题的解决方案:实际上我的用例更适合MapStruct @AfterMapping methods,我使用它并且它现在适用于所有情况:

@Mapper
public abstract class ConstraintsPostProcessor {

    @Inject
    private UserService userService; // can use normal Spring DI here

    @AfterMapping
    public void setConstraintsOnMissionTreeDTO(Mission mission, @MappingTarget MissionDTO dto){ // do not forget the @MappingTarget annotation or it will not work
        dto.setUser(userService.getCurrentUser()); // can do any additional logic here, using services etc.
    }
}

在主映射器中:

@Mapper(uses = {ConstraintsPostProcessor.class}) // just add the previous class here in the uses attribute
public interface DimensionMapper {
    ...
}