Search code examples
javadtomapstruct

Mapstruct, mapping to nested objects from sevral input parameters


Given a set of five objects:

KeyDto{String id}

ValueDto{String name, String value, String description}

Key{String id, String name}

Value{String value, String description}

Target{Key key, Value value}

I would like to create a mapper with two parameters:

 Target dtosToTarget(KeyDto keyDto, ValueDto valueDto);

However, just defining helper methods for Key and Value seems not to be enough:

@Mapping(source = "keyDto.id", target = "id")
@Mapping(source = "valueDto.name", target = "name")
Key keyDtoAndValueDtoToKey(KeyDto keyDto, ValueDto valueDto);

Value valueDtoToValue(ValueDto valueDto);

This gives an error on the actual dtosToTarget method:

Error:(17, 19) java: Can't map property "java.lang.String value" to "mapping.Value value". Consider to declare/implement a mapping method: "mapping.Value map(java.lang.String value)".

The only solution I could think of - is defining custom java expressions to call necessary methods, like

@Mapping(target = "key", expression = "java(keyDtoAndValueDtoToKey(keyDto, valueDto))")
@Mapping(target = "value", expression = "java(valueDtoToValue(valueDto))")

Is there a cleaner approach?


Solution

  • The error you are seeing is because by default MapStruct will try to map valueDto.value into Target.value which is String to Value.

    However, you can configure this like this:

    @Mapper
    public MyMapper {
    
        @Mapping( target = "key.id", source = "keyDto.id")
        @Mapping( target = "key.name", source = "valueDto.name")
        @Mapping( target = "value", source = "valueDto")
        Target dtosToTarget(KeyDto keyDto, ValueDto valueDto);
    
        Value valueDtoToValue(ValueDto valueDto);
    }