Reputation: 3841
My mapper:
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface HoursLocRecord_to_MasterHoursDtoMapper extends StandardMapper<HoursLocRecord, MasterHoursDto> {
@Mapping(source = "totalOperatingHours.value", target = "totalHours")
@Mapping(source = "trigger.value", target = "trigger")
MasterHoursDto map(HoursLocRecord data);
}
Target bean:
public class HoursDto implements IAssetInfo, Serializable {
private Double totalHours;
private Long trigger;
}
Source bean:
public class HoursLocRecord implements Serializable {
protected ParsedDecimal totalOperatingHours;
protected ParsedUnsignedShort trigger;
}
ParsedUnsignedShort
public class ParsedUnsignedShort {
protected int value;
}
So you can see above that Trigger is an ParsedUnsignedShort in the 'source' and a Long in the 'target'. There is a name collision somewhere as I am getting this:
Error:(42, 6) java: Can't map property "cat.tmatic.mh.domain.pl6xx.ParsedUnsignedShort trigger" to "java.lang.Long trigger". Consider to declare/implement a mapping method: "java.lang.Long map(cat.tmatic.mh.domain.pl6xx.ParsedUnsignedShort value)".
The strange thing is I am not mapping those two! I am mapping trigger.value to trigger. I think I am getting a name collision but cannot overcome it. We had to rename one variable to overcome this but mapstruct must be smarter than that. Help!
Thanks to Rohan Bhattacharya below I remade my test without the StandardMapper.class (he didn't use it) that I was extending. It compiled.
public interface StandardMapper<From, To> {
/**
* Maps from one object to another.
*/
To map(From from);
/**
* Update the object.
*/
To update(From from, @MappingTarget To to);
}
So then I hooked it back up and removed the 'update' method and bam, it compiled. Apparently when using the @MappingTarget annotation I am getting the above error. The generated code must try to use/create the same method and I get the mappingError. Since I don't need the 'update' I can remove it and call this closed, but I think this is still a bug in Mapstruct.
Upvotes: 2
Views: 3665
Reputation: 4140
If I understand you correctly, you effectively created a mapper like this (note, extends missing):
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface HoursLocRecord_to_MasterHoursDtoMapper {
// your overriden method To map(From from);
@Mapping(source = "totalOperatingHours.value", target = "totalHours")
@Mapping(source = "trigger.value", target = "trigger")
MasterHoursDto map(HoursLocRecord data);
// no mappings defined here, so MapStruct will try to generate
// those missing mapping based on name similarity.
MasterHoursDto update(HoursLocRecord from, @MappingTarget MasterHoursDto to);
If you want to keep using the base class you could do something like this:
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface HoursLocRecord_to_MasterHoursDtoMapper extends StandardMapper<HoursLocRecord, MasterHoursDto> {
@Mapping(source = "totalOperatingHours.value", target = "totalHours")
@Mapping(source = "trigger.value", target = "trigger")
MasterHoursDto map(HoursLocRecord data);
@InheritConfiguration // tell MapStruct to apply the same mappings as the method above with the same source / target
MasterHoursDto update(HoursLocRecord from, @MappingTarget MasterHoursDto to);
Upvotes: 1