Reputation: 276
I am trying to use Mapstruct to map source object to a target list. What should be a clean mapstruct way of doing this?
Below are my DTO's.
Source DTO
@Data
class Source
{
String a;
String b;
String C;
}
Target DTO
@Data
class Target
{
String name;
List<Child> customList;
}
@Data
class Child
{
String attr1;
boolean attr2;
}
I am facing issues with Mapper Class. Trying to achieve something like below.
public interface CustomMapper
{
@Mapper(target="customList" expression="java(new Child(a,false))"
@Mapper(target="customList" expression="java(new Child(b,true))"
@Mapper(target="customList" expression="java(new Child(c,false))"
Target sourceToTarget(Source source);
}
I don't want to use qualifiedBy function like below to achieve this, as all conversion needs to be coded for each element.
List<Child> toList(Source source)
{
List<Child> customList = new ArrayList<Child>();
customList.add(new Child(source.getA(),false));
customList.add(new Child(source.getB(),true));
customList.add(new Child(source.getC(),false));
return customList;
}
Upvotes: 8
Views: 36801
Reputation: 2093
I have used an expression to solve this problem. The expression is to perform the mapping (for objects, straightforward for Strings), and then convert it to a list.
@Mapping(target = "names", expression = "java(Arrays.asList(map(source.getName())))")
TargetObject map(SourceObject source);
TargetName map(SourceName source)
You need to import "Arrays" class in the @Mapper definition as below.
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring", imports = {Arrays.class})
Upvotes: 11
Reputation: 11115
I had similar use case where i want to convert and Single Object
to List
of objects.
As these are very custom requirements, will be hard for mapstruct
to provide some API for use cases like this.
I ended up implementing using default method
like this
@Mapper(componentModel = "spring")
interface MyMapper {
default List<SomeObject> from(SourceObject sourceObject) {
//Add Mappig logic here
//return the list
}
}
//If you want to use some mapper for mapping
@Mapper(componentModel = "spring")
public abstract class SomeArrayMapper {
@Autowired
SomeMapper mapper;
public SomeUser[] from(SingleObject singleObject) {
SomeUsers[] Users = new SomeUser[1];
Users[0] = mapper.toUser(singleObject);;
return Users ;
}
}
In some cases Decorators can also be useful take a look at here
Upvotes: 6
Reputation: 4170
There is no clean way of doing this at the moment in MapStruct. MapStruct is considerring bean tot map mapping. See here: https://github.com/mapstruct/mapstruct/pull/1744 which might come in helpful once implemented.
However, if you really have a lot of properties and this is a recurring problem, and you dislike reflection - like I do - you might want to give code generation an attempt and DIY. I posted an example some while ago for generating a mapper repository here: https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-mapper-repo but, it's a bit of an steep learning curve.. sorry
Upvotes: 2