-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Expected behavior
using @Mapping( target = ".", source = "record" ) should be equivalent as adding several @Mapping( target = "x", source = "record.x" ) for all the properties on 'record' (unless there is already another explicit @Mapping with it).
Source: https://mapstruct.org/documentation/dev/reference/html/#mapping-nested-bean-properties-to-current-target
In particular, a code like this one:
@Mapper
public interface Example {
record Sample(
String first,
String second,
String third
) {}
@Mapping(target = ".", source = "main")
@Mapping(target = "third", source = "secondary.third")
Sample merge(Sample main, Sample secondary);
}Should be valid and generate a mapping equivalent to return new Sample(main.first, main.second, secondary.third).
From a user perspective, this mapping means: 'Use everything from main, except 'third' from secondary.
Actual behavior
With the code above, mapstructs reports the following two errors:
Several possible source properties for target property "first".
Several possible source properties for target property "second".It appears that the @Mapping(target = ".", source = "main") is not used for disambiguation.
Steps to reproduce the problem
Here are other examples with different outcomes:
Specify all fields: works
The following code:
@Mapper
public interface Example {
record Sample(
String first,
String second,
String third
) {}
@Mapping(target = "first", source = "main.first")
@Mapping(target = "second", source = "main.second")
@Mapping(target = "third", source = "secondary.third")
Sample merge(Sample main, Sample secondary);
}Correctly compiles are generates the expected mapping (equivalent to return new Sample(main.first, main.second, secondary.third))
Secondary object without duplicated fields: works
The following code:
@Mapper
public interface Example {
record Sample(
String first,
String second,
String third
) {}
record DifferentSample(
String third
) {}
@Mapping(target = ".", source = "main")
@Mapping(target = "third", source = "secondary.third")
Sample merge(Sample main, DifferentSample secondary);
}Correctly compiles are generates the expected mapping (equivalent to return new Sample(main.first, main.second, secondary.third)).
In this case there is no ambiguity.
Double target=".": same outcome
The following two pieces of code:
@Mapper
public interface Example {
record Sample(
String first,
String second,
String third
) {}
@Mapping(target = ".", source = "main")
@Mapping(target = ".", source = "secondary")
@Mapping(target = "third", source = "secondary.third")
Sample merge(Sample main, Sample secondary);
}@Mapper
public interface Example {
record Sample(
String first,
String second,
String third
) {}
@Mapping(target = "third", source = "secondary.third")
Sample merge(Sample main, Sample secondary);
}Generates the same outcome as the 'expected behavior' example: Several possible source properties for target property "first"/"second".
Based on this it appears as if something like @Mapping(target = ".", source = "value") is implicitly added to all mappings with a single parameter value, which means that explicitly adding it doesn't really do anything, instead of disambiguating.
Extra, if this were working as expected, suggestions like #3161 would not need any extra 'PrimaryMapping' annotation, as that would be fixed with a target="." mapping.
@Mapping(target = "borrowed", source = "tblB.borrowed")
@Mapping(target = ".", source = "tblA")
EntityA toEntity(TblA tblA, TblB tblB)MapStruct Version
1.6.3