Skip to content
Advertisement

MapStruct mapper based on type

Consider the following simplified structure (that has both a DO and a DTO for each):

Component {
   UUID id;
   String name;
}

MotherboardComponent extends Component {
    String type;
    List<Component> components;
}

For both I have a mapper that does the mapping between the DO and DTO, However, I am facing a problem and don’t really know how to handle it. If for the MotherboardComponent in the list I have another MotherboardComponent, the resulting mapped object is to ComponentDO and not to MotherboardComponentDO.

How can I tell MapStruct to use the MotherboardComponentMapper inside the MotherboardComponentMapper, if the object is actually an extended one, not a base?

Thanks

Advertisement

Answer

MapStruct does not do anything on runtime. It once knows about the types during compilation time.

In order to solve this problem you will have to help it a bit:

e.g.

@Mapper
public abstract class MotherboardComponentMapper {

    public abstract MotherboardComponentDO map(MotherboardComponent component);

    public ComponentDO map(Component component) {
        if (component instanceof MotherboardComponent) {
            return map((MotherboardComponent) component);
        }

        return mapAsComponentDO(component);
    }

    @Named("asComponentDO")
    protected abstract ComponentDO mapAsComponentDO(Component component);

}

Since we have marked the mapAsComponentDO with @Named MapStruct will not treat it is a possible method for mapping from Component to ComponentDO and it will use the map(Component) method instead.

There is an open issue for supporting such down cast mapping in the MapStruct issue tracker.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement