Reputation: 3686
I am trying to figure out how to implement the following mapping:
class SuperComplexClass {
Long value;
String description;
}
class MapIntoMe {
// Many other fields that is also mapped
SuperComplexClass superComplexObject;
}
class MapFromMe {
ComplexClassPart1 complexClassPart;
}
class AdditionalData {
ComplexClassPart2 complexClassPart;
}
@Mapper
public interface SomeFancyMapper {
@Mapping(target = "superComplexObject", source = "{mfm.complexPart, ad.complexPart}",
qualifiedByName = "mapSuperComplexObject")
MapIntoMe mapFromMeIntoMe(MapFromMe mfm, AdditionalData ad);
@Named("mapSuperComplexObject")
default SuperComplexClass mapSuperComplexObject(ComplexPart1 p1, ComplexPart2 p2) {
SuperComplexClass superObject = new SuperComplexClass();
//some logic that calculates and fills superObject]
return superObject;
}
}
And now obviously expression like source = "{mfm.complexPart, ad.complexPart}"
is not working, but it shows clearly what I would like to achieve.
So far I wasn't able to find the answer if that's possible with this approach and without some ugly workarounds.
Any ideas?
Upvotes: 2
Views: 8292
Reputation: 21471
Currently it is not supported to reuse mapping methods with more than one parameter. That is why something like the expression you shared doesn't work.
However, you could use expression
, @AfterMapping
or @Context
(in case you don't need to use AdditionalData
for other mapping) to achieve what you need.
@Mapper
public interface SomeFancyMapper {
@Mapping(target = "superComplexObject", expression = "java(mapSuperComplexObject(mfm.getComplexPart(), ad.getComplexPart()))")
MapIntoMe mapFromMeIntoMe(MapFromMe mfm, AdditionalData ad);
default SuperComplexClass mapSuperComplexObject(ComplexPart1 p1, ComplexPart2 p2) {
SuperComplexClass superObject = new SuperComplexClass();
//some logic that calculates and fills superObject]
return superObject;
}
}
@AfterMapping
@Mapper
public interface SomeFancyMapper {
@Mapping(target = "superComplexObject", ignore = true)
MapIntoMe mapFromMeIntoMe(MapFromMe mfm, AdditionalData ad);
@AfterMapping
default void mapSuperComplexObject(@MappingTarget MapIntoMe target, MapFromMe mfm, AdditionalData ad) {
SuperComplexClass superObject = new SuperComplexClass();
//some logic that calculates and fills superObject]
return superObject;
}
}
@Context
@Mapper
public interface SomeFancyMapper {
@Mapping(target = "superComplexObject", source = "complexPart",
qualifiedByName = "mapSuperComplexObject")
MapIntoMe mapFromMeIntoMe(MapFromMe mfm, @Context AdditionalData ad);
@Named("mapSuperComplexObject")
default SuperComplexClass mapSuperComplexObject(ComplexPart1 p1, @Context AdditionalData ad) {
SuperComplexClass superObject = new SuperComplexClass();
//some logic that calculates and fills superObject]
return superObject;
}
}
Keep in mind that when using @Context
the parameter annotated with that annotation cannot be used in Mapping#target
. It is an additional context that can be passed to other mapping methods or lifecycle methods.
Upvotes: 5