MapStruct: Как сделать мой метод отображения из Long в Object? - PullRequest
0 голосов
/ 27 января 2020

У меня есть Entity и DTO для него.

@Entity
@Data
public class GroupParameter {

    @Id
    @GeneratedValue(generator = ID_GENERATOR)
    private Long id;
    private String title;
    private boolean common;
    @ManyToOne
    @JoinColumn(name = "TYPE_REPORT_ID", nullable = false)
    private TypeReport typeReport;

}

@Data
public class GroupParameterIdDTO extends GroupParameterAbstract {

    private Long typeReportId;

}

Когда я сопоставляю DTO с Entity, мне нужно сопоставить Long typeReportId с TypeReport typeReport.

Я пытаюсь сделать это так :

@Mapper(componentModel = "spring")
public abstract class GroupParameterMapper {

    @Autowired
    private TypeReportService typeReportService;

    @Mapping(target = "typeReport", source = "typeReportId", qualifiedByName = "fromLongToTypeReport")
    public abstract GroupParameter fromGroupParameterIdDTO(GroupParameterIdDTO groupParameterIdDTO);

    @Named("fromLongToTypeReport")
    private TypeReport fromLongToTypeReport(Long typeReportId) throws EntityNotFoundException {
        return typeReportService.findById(typeReportId);
    }
}

Но я получаю ошибку:

Ошибка: (23,5) java: Невозможно сопоставить свойство "java .lang.Long typeReportId" в "ru.watchlist.domain.TypeReport typeReport". Попробуйте объявить / реализовать метод сопоставления: «ru.watchlist.domain.TypeReport map (java .lang.Long value)».

Как сопоставить Long для Object, найдя Object в Репозиторий по идентификатору?

Ответы [ 3 ]

2 голосов
/ 27 января 2020

Все методы, которые используются в квалификаторах, должны быть доступны для класса реализации. В настоящее время fromLongToTypeReport является приватным. Вы должны сделать это package-protected, protected или public, и это будет работать.


На боковом узле вам не нужно использовать квалификаторы для отображения между Long и TypeRecord. Вы можете просто определить такой метод, и MapStruct сможет выполнить сопоставление.

@Mapper(componentModel = "spring")
public abstract class GroupParameterMapper {

    @Autowired
    private TypeReportService typeReportService;

    @Mapping(target = "typeReport", source = "typeReportId")
    public abstract GroupParameter fromGroupParameterIdDTO(GroupParameterIdDTO groupParameterIdDTO);

    protected TypeReport fromLongToTypeReport(Long typeReportId) throws EntityNotFoundException {
        return typeReportService.findById(typeReportId);
    }
}
0 голосов
/ 05 февраля 2020

Вы должны немного исправить свой код (изменить исходное значение). MapStruct читает имя параметров в методе карты:

@Mapper(componentModel = "spring")
public abstract class GroupParameterMapper {

    @Autowired
    private TypeReportService typeReportService;

    @Mapping(target = "typeReport", source = "groupParameterIdDTO", qualifiedByName = "fromLongToTypeReport")
    public abstract GroupParameter fromGroupParameterIdDTO(GroupParameterIdDTO groupParameterIdDTO);

    @Named("fromLongToTypeReport")
    private TypeReport fromLongToTypeReport(GroupParameterIdDTO groupParameterIdDTO) throws EntityNotFoundException {
        return typeReportService.findById(groupParameterIdDTO.getTypeReportId());
    }
}
0 голосов
/ 27 января 2020

Я сделал это с помощью qualByName следующим образом:

import java.util.List;
@Mapper(componentModel = "spring", uses = { IdTranslator.class})
public interface GroupParameterMapper {

//...

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "typeReport", source ="typeReportId", qualifiedByName = { "idTranslator", "toTypeReport" })
    GroupParameter fromGroupParameterIdDTO(GroupParameterIdDTO groupParameterIdDTO) throws EntityNotFoundException;

//...
}

@Named("IdTranslator")
public class IdTranslator {

    @Autowired
    TypeReportService typeReportService;

    @Named("toTypeReport")
    public TypeReport toTypeReport(Long typeReportId) throws EntityNotFoundException {

        if (typeReportId != null) {
            return typeReportService.findById(typeReportId);
        } else {
            return null;
        }
    }


}

Я не знаю, почему я должен использовать @Named перед классом (так это сделано в официальном руководстве), потому что без него это работает хорошо.

...