У меня есть класс 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.
Это работает, если:
Какой должна быть конфигурация, чтобы сообщить mapStruct, чтобы не отображать поля суперкласса?




Это потому, что класс модели имеет другой набор полей, чем DTO, и ваш картограф отображает в обоих направлениях. Но это вполне естественно, у dto нет идентификатора.
Обходным путем может быть исключение этих полей из сопоставления, например, путем аннотации id и других полей в классе модели, которые не находятся в dto: Mapping("this").
У меня есть другие DTO и картографы, которые не требуют ResourceSupport, и они идеально отображают поле в обоих направлениях.
Чтобы игнорировать поля в каждом конкретном случае, вы можете использовать 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?
Это будет интерфейс/класс, реализованный/расширенный всеми вашими классами сущностей. Классы DTO расширяются ResourceSupport
Есть ли способ унаследовать несколько config? (поскольку этот подход не масштабируется) Можно применить альтернативный подход @AfterMapping, но он усложняет чтение сгенерированного картографа, так как нам нужно прыгать вперед и назад, чтобы увидеть сопоставления.
Для этого есть запрос функции, в настоящее время такой вещи из коробки нет.
Это не совсем связано с классом модели, то есть
Userздесь. Если я удалюextends ResourceSupportизUserMinimalDto, картограф отлично отобразит оба пути. ЭтоResourceSupportвызывает проблему.