Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Mapstruct from using a method in automatic mapper detection

Tags:

mapstruct

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


like image 583
usr-local-ΕΨΗΕΛΩΝ Avatar asked Aug 30 '25 16:08

usr-local-ΕΨΗΕΛΩΝ


1 Answers

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;


}
like image 154
Filip Avatar answered Sep 04 '25 01:09

Filip