Картограф не отображает правильно - mapstruct - PullRequest
2 голосов
/ 20 апреля 2020

У меня проблемы с отображением вложенного поля dto с помощью mapstruct. у меня есть пара dtos:

@Data
public class InstrumentGet {

    .....
    private MediaGet image;
    private List<LocaleGet> locales;

}
@Data
public class LocaleGet {

    private String name;
    private String description;
    private String iso6391;
    private boolean defaultLanguage;

}
@Data
public class MediaGet {
    private String uri;
    private int width;
    private int height;
}

с соответствующими преобразователями

@Mapper(componentModel = "spring")
public interface LocaleMapper {
    @Mapping(source = "culture.iso6391",target = "iso6391")
    @Mapping(source = "culture.defaultLanguage",target = "defaultLanguage")
    LocaleGet toDtoGet(BaseLocale locale);
    List<LocaleGet> toDtosGet(List<BaseLocale> locales);
}
@Mapper( componentModel = "spring")
public interface MediaMapper {

    MediaGet toDtoGet(Media media);
}
@Mapper(componentModel = "spring",uses = {MediaMapper.class, LocaleMapper.class})
public interface InstrumentMapper {
    InstrumentGet instrumentToInstrumentGet(Instrument instrument, List<BaseLocale> locales);


}

Пока все работает отлично, и сгенерированный код автоматически связывает другие необходимые средства отображения для правильного построения dtos. Например. реализации сгенерированного инструментального сопоставления

@Component
public class InstrumentMapperImpl implements InstrumentMapper {

    @Autowired
    private MediaMapper mediaMapper;
    @Autowired
    private LocaleMapper localeMapper;

    @Override
    public InstrumentGet instrumentToInstrumentGet(Instrument instrument, List<BaseLocale> locales) {
        if ( instrument == null && locales == null ) {
            return null;
        }

        InstrumentGet instrumentGet = new InstrumentGet();

        if ( instrument != null ) {
            instrumentGet.setDefaultName( instrument.getDefaultName() );
            instrumentGet.setImage( mediaMapper.toDtoGet( instrument.getImage() ) );
        }
        if ( locales != null ) {
            instrumentGet.setLocales( localeMapper.toDtosGet( locales ) );
        }

        return instrumentGet;
    }
}

Теперь у меня возникают проблемы при попытке создать преобразователь, в который вложен инструмент dto. Картограф должен использовать instrumentMapper для правильного создания необходимого dto. Dto:

@Data
    public class MemberGet {
        ......
        private MediaGet image;
        private InstrumentGet instrument;
        ......
    }

Маппер:

@Mapper(componentModel = "spring",uses = {InstrumentMapper.class, MediaMapper.class})
public interface ClientMapper {

@Mapping(source = "member.band.uid",target = "bandUid")
MemberGet toDtoMemberGet(Member member,  List<BaseLocale> locales);

}

Сгенерированный код:

@Component
public class ClientMapperImpl implements ClientMapper {

    @Autowired
    private MediaMapper mediaMapper;

    @Override
    public MemberGet toDtoMemberGet(Member member, List<BaseLocale> locales) {
        if ( member == null && locales == null ) {
            return null;
        }

        MemberGet memberGet = new MemberGet();

        if ( member != null ) {
            memberGet.setBandUid( memberBandUid( member ) );
            memberGet.setPersonDetails( member.getPersonDetails() );
            memberGet.setBirthday( member.getBirthday() );
            memberGet.setGender( member.getGender() );
            memberGet.setImage( mediaMapper.toDtoGet( member.getImage() ) );
            memberGet.setInstrument( instrumentToInstrumentGet( member.getInstrument() ) );
        }

        return memberGet;
    }

    private String memberBandUid(Member member) {
        if ( member == null ) {
            return null;
        }
        Band band = member.getBand();
        if ( band == null ) {
            return null;
        }
        String uid = band.getUid();
        if ( uid == null ) {
            return null;
        }
        return uid;
    }

    protected InstrumentGet instrumentToInstrumentGet(Instrument instrument) {
        if ( instrument == null ) {
            return null;
        }

        InstrumentGet instrumentGet = new InstrumentGet();

        instrumentGet.setDefaultName( instrument.getDefaultName() );
        instrumentGet.setImage( mediaMapper.toDtoGet( instrument.getImage() ) );

        return instrumentGet;
    }
}

Теперь медиа-маппер подобрался нормально и использует требуемый метод У меня возникла проблема с отображением инструмента, mapstruct не выполняет автоматическое подключение и вызывает необходимый метод, а вместо этого создает собственный метод, который не соответствует моим потребностям. Я явно делаю что-то не так здесь. Может ли кто-нибудь дать мне подсказку или какой-либо совет?

С уважением

1 Ответ

2 голосов
/ 20 апреля 2020

Существует ограничение в mapstruct, когда речь идет об использовании непосредственно из другого преобразователя преобразователя, который имеет несколько параметров источника. Вы можете проверить это самостоятельно, удалив один из двух параметров упомянутого преобразователя.

Вместо этого вы можете использовать @ BeforeMapping или @ AfterMapping или decoractor для решения вашей проблемы.

Параметр контекста также может работать.

...