0
votes

I have two MapStruct mapper classes where some of the target/source classes and some of the fields are exactly the same:

  ///Mapper 1
  @Mappings({
          @Mapping(target = "tenantTitleId", expression = "java(order.getProductID())"),
          @Mapping(target = "tenantId", constant = "MGM"),
          @Mapping(target = "titleName", expression = "java(order.getProductDesc())"),
          @Mapping(target = "orders", source = "order", qualifiedBy = ComplexMapper.class),
  })
  @BeanMapping(ignoreByDefault = true)
  public abstract TargetClass toTargetClass(SourceClass sourceClass) throws Exception;

  ///Mapper 2
  @Mappings({
          @Mapping(target = "tenantTitleId", expression = "java(order.getProductID())"),
          @Mapping(target = "tenantId", constant = "MGM"),
          @Mapping(target = "titleName", expression = "java(order.getProductDesc())"),
          @Mapping(target = "orders", source = "order", qualifiedBy = AnotherComplexMapper.class),
  })
  @BeanMapping(ignoreByDefault = true)
  public abstract TargetClass toTargetClass(SourceClass sourceClass) throws Exception;

The first 3 mappings are exactly the same. Is there a way to not repeat this mapping the MapStruct way?

1
If all of these mappings have the same TargetClass and different SourceClass I think that there is no way to achieve that. You can experiment with some abstract class of SourceClass and maps all similar fields in one mapping method, but I didn't test yet if mapsturct allows you to have abstract class in argument method or it needs only concrete class. You can try and let know if it helps :) - centrumek

1 Answers

0
votes

You can use Mapping Composition in order to avoid the duplication.

e.g.

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "tenantTitleId", expression = "productID"),
@Mapping(target = "tenantId", constant = "MGM"),
@Mapping(target = "titleName", expression = "productDesc"),
public @interface CommonMappings { }

And then your mapper will look like:

  ///Mapper 1
  @CommonMappings
  @Mapping(target = "orders", source = "order", qualifiedBy = ComplexMapper.class)
  @BeanMapping(ignoreByDefault = true)
  public abstract TargetClass toTargetClass(SourceClass sourceClass) throws Exception;

  ///Mapper 2
  @CommonMappings
  @Mapping(target = "orders", source = "order", qualifiedBy = AnotherComplexMapper.class)
  @BeanMapping(ignoreByDefault = true)
  public abstract TargetClass toTargetClass(SourceClass sourceClass) throws Exception;