'using mapper in another mapper method

I want to use the mapper, in another mapper in the named method, how can I do this without using Mappers.getMapper() ?

Exmaple:

@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
        unmappedTargetPolicy = ReportingPolicy.IGNORE,
        uses = {BMapper.class})
public interface AMapper {
//some methods here

@Named("getResultList")
    default List<Result> getResultList(Argument args) {
        BMapper bMapper = Mappers.getMapper(BMapper.class);
        return args.stream().map(Argument::getArg2).map(bMapper::toDto).collect(Collectors.toList());
    }

}

@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
        unmappedTargetPolicy = ReportingPolicy.IGNORE
        )
public interface BMapper {
//some methods here
    Result toDto(Arg2 arg2)
}

I know that using BMapper bMapper = Mappers.getMapper(BMapper.class) bad with componentModel = "spring", but is there any alternatives? P.S This is a simple example, but the logic in named method can be much more complicated than that presented. Ideally, I would like to use the mapper in another mapper's named method



Solution 1:[1]

I would say that you are approach should already be working 90%. For me it does with a few simple adjustments ;). The property "uses = BMapper.class" should do the trick. All you have to do is copy your

@Named("getResultList")
default List<Result> getResultList(Argument args) {
    BMapper bMapper = Mappers.getMapper(BMapper.class);
    return args.stream().map(Argument::getArg2).map(bMapper::toDto).collect(Collectors.toList());
}

into the other mapper (MapperB). Your result is then

  @Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
    unmappedTargetPolicy = ReportingPolicy.IGNORE,
    uses = BMapper.class)
  public interface AMapper {
    //some methods here
  }

  @Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
  unmappedTargetPolicy = ReportingPolicy.IGNORE)
  public interface BMapper {
    //some methods here
    Result toDto(Arg2 arg2)

    @Named("getResultList")
    default List<Result> getResultList(Argument args) {
      BMapper bMapper = Mappers.getMapper(BMapper.class);
      return args.stream().map(Argument::getArg2).map(bMapper::toDto).collect(Collectors.toList());
    }

In MapperA you can still access the "getResultList" method via

qualiviedByName = "getResultList"

as usuall.

A small sidenote. When having multiple Mappers with the same config it might be beneficial to use the @MapperConfig annotation.

@MapperConfig(
    componentModel = "spring",
    builder = @Builder(disableBuilder = true),
    // your remaining config here
)
public interface GlobalMappingConfig {
}

and simply annotate your Mappers with

@Mapper(config = GlobalMappingConfig.class)

or in case if MapperA

@Mapper(config = GlobalMappingConfig.class, uses = MapperA.class)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 GJohannes