I am trying to use ModelMapper
to map
a collection
of sub-objects to a list
of id numbers.
public class Child {
private int id;
private String childName;
}
public class Parent {
private Set<Child> children;
private String parentName;
}
public class ParentDto {
private int[] children; // Or use ArrayList<Integer>
private String parentName;
}
How do I tell ModelMapper
to flatten the set of Child objects to an array of id numbers?
My first attempt is this but does not seem correct:
modelMapper.addMappings(new PropertyMap<Parent, ParentDto>() {
@Override
protected void configure() {
using(ctx -> ctx.getSource().stream().map(Parent::getId).collect(Collectors.toList())
.map().setChildren(source.getId()));
};
});
Type listType = new TypeToken<ArrayList<ParentDto>>() {}.getType();
ArrayList<ParentDto> parentDtos = new ArrayList<>();
parentDtos = modelMapper.map(parents, listType);
The setChildren
call seems like it needs to be map().add()
but that does not work either.
Ideas are welcome.
One way of doing this is to create a Set<Child>
to int[]
converter and use it to map Parent.children
to ParentDTO.children
:
ModelMapper mapper = new ModelMapper();
Converter<Set<Child>, int[]> childSetToIntArrayConverter =
ctx -> ctx.getSource()
.stream()
.mapToInt(Child::getId)
.toArray();
mapper.createTypeMap(Parent.class, ParentDto.class)
.addMappings(map -> map
.using(childSetToIntArrayConverter)
.map(
Parent::getChildren,
ParentDto::setChildren
)
);
Here is the complete demo (using lombok 1.18.10 and modelmapper 2.3.5):
import lombok.AllArgsConstructor;
import lombok.Data;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Parent parent = new Parent();
parent.setParentName("Parent");
parent.setChildren(Set.of(
new Child(1, "A"),
new Child(2, "B"),
new Child(3, "C")
));
ModelMapper mapper = new ModelMapper();
Converter<Set<Child>, int[]> childSetToIntArrayConverter =
ctx -> ctx.getSource()
.stream()
.mapToInt(Child::getId)
.toArray();
mapper.createTypeMap(Parent.class, ParentDto.class)
.addMappings(map -> map
.using(childSetToIntArrayConverter)
.map(
Parent::getChildren,
ParentDto::setChildren
)
);
ParentDto dto = mapper.map(parent, ParentDto.class);
System.out.println(parent);
System.out.println(dto);
}
@Data
@AllArgsConstructor
public static class Child {
private int id;
private String childName;
}
@Data
public static class Parent {
private Set<Child> children;
private String parentName;
}
@Data
public static class ParentDto {
private int[] children;
private String parentName;
}
}
Output
Main.Parent(children=[Main.Child(id=3, childName=C), Main.Child(id=2, childName=B), Main.Child(id=1, childName=A)], parentName=Parent)
Main.ParentDto(children=[3, 2, 1], parentName=Parent)