Recursive mapping of collection elements?

1,791 views
Skip to first unread message

Evan Moses

unread,
Jul 28, 2016, 7:51:34 PM7/28/16
to modelmapper
Both my domain objects and my DTOs have a parent-child relationship.  The domain objects have a Collection<Child>, but the DTOs have a List<ChildDTO>.  I'm having a hard time figuring out how to configure the parent mapper to map the collections of children correctly.  For instance:

//getters & setters omitted
Parent {
   Collection<Child> children;
}

Child {
   int prop1;
}

ParentDTO {
   List<ChildDTO> children;

ChildDTO {
   String prop1; //Note that this has to be mapped 

I've already configured a PropertyMap<Child, ChildDTO> to manage the mapping of prop1.  Now I'd like to set up the PropertyMap<Parent, ParentDTO>.   If I don't have a propertyMap, it complains about the failing to convert a Collection to a List.  ModelMapper already knows how to convert Child to ChildDTO, but how do I tell it to recursively convert all the Childs to ChildDTOs in Parent?  If I do something like this, I end up having to hand-map all the properties of child (and there are many properties on the actual child object):

Converter<Collection<Child>, List<ChildDTO>> childConverter = new AbstractConverter<>() {
    List<ChildDTO> convert(Collection<Child> source) {
       source.stream().map(child -> {
             //hand convert all child properties
             return childDto;
       });
    } 
};

PropertyMap<Parent, ParentDTO> {
    configure() {
       using(childConverter).map(parent.getChildren()).setChildren(null);
    }
}

Obviously that's less than ideal because I lose the benefit of the mapping I've already set up to map Child -> ChildDTO.  But I can't figure out any way to call the mapper instance from inside the Converter.  Any help would be appreciated.

Evan Moses

unread,
Jul 28, 2016, 8:13:33 PM7/28/16
to modelmapper
OK, looks like with just a little more searching, I answered my own question.  Thank you internet-based rubber duck.  

private static final Converter<Collection<Child>, List<ChildDTO>> childConverter =
(context) -> {
    Collection<Child> source = context.getSource();
    return source.stream()
        .map(child -> {
            MappingContext<Child, ChildDTO> subContext = context.create(child, ChildDTO.class);
            return context.getMappingEngine().map(subContext);
        }).collect(Collectors.toList());
};
Reply all
Reply to author
Forward
0 new messages