admin管理员组文章数量:1288978
I have mappers CatMapper
, DogMapper
etc. which I want to use in other mappers like ZooMapper
, FarmMapper
etc. Every time I have to repeat uses = {CatMapper.class, DogMapper.class}
.
How to avoid it and "use" them together?
Attempts
Extract to constant
Extract array to constant:
public static final Class<?>[] ANIMAL_MAPPERS = {CatMapper.class, DogMapper.class};
but it's impossible to use it in an annotation attribute because "Attribute value must be constant":
@Mapper(uses = ANIMAL_MAPPERS)
Even if array constant was possible, you can't handle the case with other mappers because runtime in the attribute is not allowed e.g.:
@Mapper(uses = ArrayUtils.addAll(ANIMAL_MAPPERS, new Class[]{OtherMapper.class, YetAnotherMapper.class}))
Grouping mappers and multi-level "uses"
Create mapper that groups all repeatable mappers in uses
:
@Mapper(uses = {CatMapper.class, DogMapper.class})
public interface AllAnimalMappers {
}
and use it in every place in uses
instead of repetition:
@Mapper(uses = {AllAnimalMappers.class})
public interface ZooMapper {
But it doesn't work. MapStruct doesn't use methods from nested mappers:
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".
Config (many configs)
Create config that groups all repeatable mappers in uses
:
@MapperConfig(uses = {CatMapper.class, DogMapper.class})
public interface AllAnimalMappers {
}
and use it in config
(empty uses
):
@Mapper(config = AllAnimalMappers.class)
public interface ZooMapper {
It seems to work. But config
isn't a list/array, so you can't use many configs in one mapper, for example:
@Mapper(config = {AllAnimalMappers.class, AllBuildingMappers.class})
public interface ZooMapper {
Therefore it's very limited, you can't use it in most cases.
Generic mapper
The problem is more visible in the use cases when you have many mappers because of inheritance and impossibility to create one generic mapper for all child classes (source 1, source 2). You would like to use all extensions together.
All extension in uses
in base mapper:
@MapperConfig(uses = {CatMapper.class, DogMapper.class})
public interface AnimalMapper<T, U> {
and use it in mappers:
@Mapper(uses = {AnimalMapper.class})
public interface ZooMapper {
but it also doesn't work (same error as above).
Full example
Domain classes:
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;
}
and DTO equivalents:
@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;
}
and mappers for them:
@MapperConfig
public interface AnimalMapper<T, U> {
U toDto(T source);
}
@Mapper
public interface CatMapper extends AnimalMapper<Cat, CatDto> {
@Mapping(target = "catWhisper", source = "name")
CatDto toDto(Cat source);
}
@Mapper
public interface DogMapper extends AnimalMapper<Dog, DogDto> {
@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);
}
本文标签: javaMapStructnested multilevel quotusesquot or mappers groupingStack Overflow
版权声明:本文标题:java - MapStruct - nested multi-level "uses" or mappers grouping - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738457766a2087851.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论