Search code examples
javamappingmapstruct

MapStruct set field value to a result of another mapper method


Given classes

public static class Source {
    private int a;
    private int b;
}
public static class DataHolder {
    private int c;
}
public static class Target {
    private int a;
    private int b;
    private DataHolder holder;
}

and mapper

@Mapper
public interface SourceToDataHolderMapper {

    DataHolder sourceToDataHolder(Source src);

}

I want to implement another mapper that maps Source to Target utilizing SourceToDataHolderMapper mapper for holder field in Target type:

@Mapper
public interface SourceToTargetMapper {

    @Mapping(target = "holder", ???)
    Target sourceToTarget(Source src);

}

I don't know what to use in place of ??? so that Mapstruct would use my SourceToDataHolderMapper correctly.

I tried setting import and uses for type SourceToDataHolderMapper in @Mapper annotation, but it wasn't working.


Solution

  • After a few dirty attempts of using expression="java(...)" for @Mapping annotation I found a solution:

    @Mapper(uses = SourceToDataHolderMapper.class)
    public interface SourceToTargetMapper {
    
        @Mapping(target = "holder", source = ".")
        Target sourceToTarget(Source src);
    
    }
    

    Which generates implementation code like this:

    public static class SourceToTargetMapperImpl {
        private SourceToDataHolderMapper sourceToDataHolderMapper = Mappers.getMapper(SourceToDataHolderMapper.class);
    
        public Target sourceToTarget(Source src) {
            if ( src == null ) return null;
            Target target = new Target();
            target.setA( src.getA() );
            target.setB( src.getB() );
            target.setHolder( sourceToDataHolderMapper.sourceToDataHolder( src ) );
        }
    
    }
    

    That is exactly what I wanted without using expression