Какова будет конфигурация для mapStruct, чтобы остановить отображение полей суперкласса DTO?

У меня есть класс DTO, который расширяет класс spring-hateoasResourceSupport. UserMinimalDto — это DTO для объекта User.

Итак, для создания классов картографа я использую картаСтруктура.

@Data //from lambok
@EqualsAndHashCode(callSuper=false)
public class UserMinimalDto extends ResourceSupport {

    String firstName;
    String lastName;
    String email;
    String uniqueId;
    String profilePicUrl;

}

Я использую ResourceSupport, чтобы добавить ссылки ненависти к ответу от контроллера.

Интерфейс картографа

@Mapper
public interface UserMinimalMapper {

    UserMinimalMapper INSTANCE = Mappers.getMapper(UserMinimalMapper.class) ;

    UserMinimalDto entityToDto(User user);

    User dtoToEntity(UserMinimalDto userMinimalDto);
}

Но когда я запускаю mvn clean install в проекте, я сталкиваюсь с ошибкой компиляции.

Can't map property "org.springframework.hateoas.Link id" to "java.lang.Integer id". Consider to declare/implement a mapping method: "java.lang.Integer map(org.springframework.hateoas.Link value)".

Это потому, что mapStruct пытается сопоставить поля ResourceSupport. Это работает, если:

  1. Я удаляю расширения ResourceSupport из UserMinimalDto
  2. Я удаляю dtoToEntity(UserMinimalDto userMinimalDto); от картографа интерфейс

Какой должна быть конфигурация, чтобы сообщить mapStruct, чтобы не отображать поля суперкласса?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 530
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это потому, что класс модели имеет другой набор полей, чем DTO, и ваш картограф отображает в обоих направлениях. Но это вполне естественно, у dto нет идентификатора.

Обходным путем может быть исключение этих полей из сопоставления, например, путем аннотации id и других полей в классе модели, которые не находятся в dto: Mapping("this").

Это не совсем связано с классом модели, то есть User здесь. Если я удалю extends ResourceSupport из UserMinimalDto, картограф отлично отобразит оба пути. Это ResourceSupport вызывает проблему.

Puspender 24.03.2019 10:43

У меня есть другие DTO и картографы, которые не требуют ResourceSupport, и они идеально отображают поле в обоих направлениях.

Puspender 24.03.2019 10:44
Ответ принят как подходящий

Чтобы игнорировать поля в каждом конкретном случае, вы можете использовать Mapping#ignore.

В вашем случае это будет выглядеть так:

@Mapper
public interface UserMinimalMapper {

    UserMinimalMapper INSTANCE = Mappers.getMapper(UserMinimalMapper.class) ;

    UserMinimalDto entityToDto(User user);

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "links", ignore = true)
    User dtoToEntity(UserMinimalDto userMinimalDto);
}

Если у вас есть общий интерфейс/класс для ваших сущностей, вы можете использовать @MapperConfig и определить эти исключения.

Это может выглядеть примерно так:

@MapperConfig(mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG)
public interface CommonMappingConfig {

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "links", ignore = true)
    BaseEntity map(ResourceSupport resourceSupport);

}

@Mapper(config = CommonMappingConfig.class)
public interface UserMinimalMapper {

    UserMinimalMapper INSTANCE = Mappers.getMapper(UserMinimalMapper.class) ;

    UserMinimalDto entityToDto(User user);

    User dtoToEntity(UserMinimalDto userMinimalDto);
}

что бы здесь было BaseEntity? Интерфейс/класс, реализованный всеми моими классами сущностей? или классы DTO?

Puspender 24.03.2019 11:49

Это будет интерфейс/класс, реализованный/расширенный всеми вашими классами сущностей. Классы DTO расширяются ResourceSupport

Filip 24.03.2019 11:52

Есть ли способ унаследовать несколько config? (поскольку этот подход не масштабируется) Можно применить альтернативный подход @AfterMapping, но он усложняет чтение сгенерированного картографа, так как нам нужно прыгать вперед и назад, чтобы увидеть сопоставления.

Leonid Dashko 14.05.2020 10:10

Для этого есть запрос функции, в настоящее время такой вещи из коробки нет.

Filip 17.05.2020 21:35

Другие вопросы по теме