My source type is a superclass with a certain set of properties, with a subclass that adds additional properties. My target type contains properties to be mapped from the superclass, as well as some optional properties to be mapped if the source is an instance of the subclass. It would be convenient to be able to be able to express this mapping relationship in a single annotation-based mapping method, rather than using multiple mapping methods with a custom mapping method to tie them together.
This is certainly related to #131, and possibly involves the same solution. The difference is that that issue concerns mapping to different target types based on the source type, whereas this involves mapping different target types to a single source type, with optional fields for subclasses.
Example
Types
public class Source {
private String property1;
private String property2;
private String property3;
// Getters, setters, & constructors omitted for brevity
}
public class SourceSubclass extends Source {
private String subclassProperty;
private String target5;
// Getters, setters, & constructors omitted for brevity
}
public class Target {
private String target1;
private String target2;
private String target3;
private String target4;
private String target5;
// Getters, setters, & constructors omitted for brevity
}
Mapper
This is an solution to the problem using the features currently available in MapStruct.
@Mapper
public interface SourceMapper {
default Target map(Source source) {
if (source instanceof SourceSubclass) {
return mapSubclass((SourceSubclass) source);
} else {
return mapSuperclass(source);
}
}
@Mapping(target = "target1", source = "property1")
@Mapping(target = "target2", source = "property2")
@Mapping(target = "target3", source = "property3")
@Mapping(target = "target4", expression = "java(null)")
@Mapping(target = "target5", expression = "java(null)")
Target mapSuperclass(Source source);
@InheritConfiguration(name = "mapSuperclass")
@Mapping(target = "target4", source = "subclassProperty")
@Mapping(target = "target5") // Have to declare in order to override with default behavior
Target mapSubclass(SourceSubclass source);
}
My source type is a superclass with a certain set of properties, with a subclass that adds additional properties. My target type contains properties to be mapped from the superclass, as well as some optional properties to be mapped if the source is an instance of the subclass. It would be convenient to be able to be able to express this mapping relationship in a single annotation-based mapping method, rather than using multiple mapping methods with a custom mapping method to tie them together.
This is certainly related to #131, and possibly involves the same solution. The difference is that that issue concerns mapping to different target types based on the source type, whereas this involves mapping different target types to a single source type, with optional fields for subclasses.
Example
Types
Mapper
This is an solution to the problem using the features currently available in MapStruct.