I have a Mapstruct mapper where I must do some String conversion service. Namely, from a list of natural-language phrases to an opaque constant defined in a utility class. No, I won't be using enums this time. It involves some Levenshtein check with a list of predefined wordings.
I have a method String getSyntheticDescription(String description) in a Spring bean that I want to use to map a single String field in my DTO.
If i use Mapstruct's uses attribute in @Mapping, I have found Mapstruct will abuse definedBean.getSyntheticDescription all around String conversions. Basically every String field mapping to a String is passed to definedBean.getSyntheticDescription, which is obviously not what I want.
I want to use that in an expression attribute for a single field only.
How do I tell Mapstruct not to try to use all available methods for mapping and specifically ignore getSyntheticDescription unless instructed otherwise?
Code
@Mapper(componentModel = "spring", uses = {TaxonomyStringParser.class, TaxonomyCustomerLogic.class})
public interface TaxonomyControlMapping {
@Mapping(target = "notcompliant", source = "nonConforme")
@Mapping(target = "withurgency", source = "nonConformeConCriticita")
@Mapping(target = "compliant", source = "conforme")
@Mapping(target = "perimeter", expression = "java(taxonomyCustomerLogic.getControlPerimeterValueFromDescription(dto.getPerimetroAnalisi()))")
@Mapping(target = "sampling", source = "campionamento")
@Mapping(target = "performer", source = "performer")
TaxonomyControlVersion fromMasterDbDto(TaxonomyControlMasterDbDTO dto) throws ParseException;
}
Results in
taxonomyControlVersion.setInstructions( taxonomyCustomerLogic.getControlPerimeterValueFromDescription( dto.getIndicazioniValutazione() ) );
taxonomyControlVersion.setSignificance( taxonomyCustomerLogic.getControlPerimeterValueFromDescription( dto.getSignificativita() ) ); //BAD
taxonomyControlVersion.setSamplingmode( taxonomyStringParser.parseSamplingModeType( dto.getModalitaCampionamento() ) ); //BAD
taxonomyControlVersion.setPerimeter( taxonomyCustomerLogic.getControlPerimeterValueFromDescription(dto.getPerimetroAnalisi()) ); //GOOD
In order for a method to only be used in a specific use case it needs to be annotated with @Named from org.mapstruct or a custom @Qualifier also from org.mapstruct.
In your case you can add @Named("syntheticDescription") to your method in the Spring bean and then use Mapping#qualifiedByName.
e.g.
@Mapper(componentModel = "spring", uses = {TaxonomyStringParser.class, TaxonomyCustomerLogic.class})
public interface TaxonomyControlMapping {
@Mapping(target = "notcompliant", source = "nonConforme")
@Mapping(target = "withurgency", source = "nonConformeConCriticita")
@Mapping(target = "compliant", source = "conforme")
@Mapping(target = "perimeter", source = "perimetroAnalisi" qualifiedByName = "syntheticDescription" )
@Mapping(target = "sampling", source = "campionamento")
@Mapping(target = "performer", source = "performer")
TaxonomyControlVersion fromMasterDbDto(TaxonomyControlMasterDbDTO dto) throws ParseException;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With