markthegrea
markthegrea

Reputation: 3841

How do I overcome a naming conflict using Mapstruct

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!

UPDATE

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

Answers (1)

Sjaak
Sjaak

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

Related Questions