Как его избежать и «использовать» их вместе?
Попытки
Извлекать в постоянную < /h4>
извлечь массив в постоянную: < /p>
public static final Class[] ANIMAL_MAPPERS = {CatMapper.class, DogMapper.class};
но его невозможно использовать в атрибуте аннотации, поскольку «Значение атрибута должно быть постоянным»:
@Mapper(uses = ANIMAL_MAPPERS)
< /code>
Даже если массивная постоянная была возможна, вы не можете обрабатывать дело с другими картинами, потому что время выполнения в атрибуте не разрешено, например, ::
@Mapper(uses = ArrayUtils.addAll(ANIMAL_MAPPERS, new Class[]{OtherMapper.class, YetAnotherMapper.class}))
Группирование картографов и многоуровневых «использований»
Создайте картограф, который группирует все повторяющиеся картографы в использовании:@Mapper(uses = {CatMapper.class, DogMapper.class})public interface AllAnimalMappers {
}
и используйте его в каждом месте использования вместо повторения:
@Mapper(uses = {AllAnimalMappers.class})
public interface ZooMapper {
Но это не работает. MapStruct не использует методы вложенных картографов:
ZooMapper.java:[10,12] Unmapped target property: "catWhisper". Mapping from property "Cat cat" to "CatDto cat".
ZooMapper.java:[10,12] Unmapped target property: "dogCall". Mapping from property "Dog dog" to "DogDto dog".
Конфигурация (множество конфигураций)
Создайте конфигурацию, которая группирует все повторяющиеся картографы в использовании:@MapperConfig(uses = {CatMapper.class, DogMapper.class})
public interface AllAnimalMappers {
}
и используйте его в конфигурации (пустое использование):
@Mapper(config = AllAnimalMappers.class)
public interface ZooMapper {
Кажется, работает. Но config не является списком/массивом, поэтому вы не можете использовать много конфигов в одном сопоставителе, например:
@Mapper(config = {AllAnimalMappers.class, AllBuildingMappers.class})
public interface ZooMapper {
Поэтому он очень ограничен, и в большинстве случаев его нельзя использовать.
Общий картограф
Проблема более заметна в случаях использования, когда у вас много преобразователей из-за наследования и невозможности создать один общий преобразователь для всех дочерних классов (источник 1, источник 2). Вы хотите использовать все расширения вместе.Все расширения используются в базовом сопоставителе:
@MapperConfig(uses = {CatMapper.class, DogMapper.class})
public interface AnimalMapper {
и используйте его в картографах:
@Mapper(uses = {AnimalMapper.class})
public interface ZooMapper {
но это также не работает (та же ошибка, что и выше).
Полный пример
Домен занятия:
public abstract class Animal {
}
@Data
public class Cat {
private String name;
}
@Data
public class Dog extends Animal {
private String name;
}
// and more extends Animal
@Data
public class Zoo {
private String name;
private Cat cat;
private Dog dog;
}
@Data
public class Farm {
private String name;
private Cat cat;
private Dog dog;
}
и эквиваленты DTO:
@Data
public abstract class AnimalDto {
}
@Data
public class CatDto extends AnimalDto {
private String catWhisper;
}
@Data
public class DogDto extends AnimalDto {
private String dogCall;
}
// and more extends AnimalDto
@Data
public class ZooDto {
private String title;
private CatDto cat;
private DogDto dog;
}
@Data
public class FarmDto {
private String companyName;
private CatDto cat;
private DogDto dog;
}
и картографы для них:
@MapperConfig
public interface AnimalMapper {
U toDto(T source);
}
@Mapper
public interface CatMapper extends AnimalMapper {
@Mapping(target = "catWhisper", source = "name")
CatDto toDto(Cat source);
}
@Mapper
public interface DogMapper extends AnimalMapper {
@Mapping(target = "dogCall", source = "name")
DogDto toDto(Dog source);
}
@Mapper(uses = {CatMapper.class, DogMapper.class})
public interface ZooMapper {
@Mapping(target = "title", source = "name")
ZooDto toDto(Zoo source);
}
@Mapper(uses = {CatMapper.class, DogMapper.class})
public interface FarmMapper {
@Mapping(target = "companyName", source = "name")
FarmDto toDto(Farm source);
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... s-grouping