Search code examples
javamappingmapstruct

Mapstruct: a particular case of shared mappings


In one mapper, I have this method

@Mapping(target = "n", source = "nome")
@Mapping(target = "c", source = "cognome")
@Mapping(target = "s", source = "sesso")
@Mapping(target = "CF", source = "codiceFiscaleOPartitaIva")
@Mapping(target = "co", source = "luogoNascita")
@Mapping(target = "p", source = "provinciaNascita")
@Mapping(target = "na", source = "nazioneNascita") // temporaneo
@Mapping(target = "d", source = "dataNascita", qualifiedByName = "XMLGregorianCalendarConvert")
@Mapping(target = "RSD", source = "denominazione")
@Mapping(target = "FN", source = "forzaNome")
@Mapping(target = "FC", source = "forzaCodiceFiscale")
@Mapping(target = "FCo", source = "forzaComune")
@Mapping(target = "NR", source = "numeroRea")
@Mapping(target = "PC", source = "provinciaCCIAA")
com.***.cmp.cgw.model.reportpersona.CAURequest.DI toDI(DittaIndividualeDTO source)

In another mapper, I have this method

@Mapping(target = "n", source = "nome")
@Mapping(target = "c", source = "cognome")
@Mapping(target = "s", source = "sesso")
@Mapping(target = "CF", source = "codiceFiscaleOPartitaIva")
@Mapping(target = "co", source = "luogoNascita")
@Mapping(target = "p", source = "provinciaNascita")
@Mapping(target = "na", source = "nazioneNascita") // temporaneo
@Mapping(target = "d", source = "dataNascita", qualifiedByName = "XMLGregorianCalendarConvert")
@Mapping(target = "RSD", source = "denominazione")
@Mapping(target = "FN", source = "forzaNome")
@Mapping(target = "FC", source = "forzaCodiceFiscale")
@Mapping(target = "FCo", source = "forzaComune")
@Mapping(target = "NR", source = "numeroRea")
@Mapping(target = "PC", source = "provinciaCCIAA")
com.***.cmp.cgw.model.reportimpresa.CAURequest.DI toDI(DittaIndividualeDTO source);
  • The mapping configurations are exactly the same, as you see
  • The two "DI" classes are in fact identical, but auto-generated in differente packages, and I am forced to use both of them
  • The source is identical in both methods
  • I cannot create a superclass or interface to be inherithed from the two DI classes

In this situation, how can I use only one configuration of mappings, to be shared between the two cases?


Solution

  • You can create an annotation that you annotate with these annotations. Then you annotate your methods with that new annotation.

    For instance:

    @Retention(RetentionPolicy.CLASS)
    @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
    @Mapping(target = "n", source = "nome")
    @Mapping(target = "c", source = "cognome")
    @Mapping(target = "s", source = "sesso")
    @Mapping(target = "CF", source = "codiceFiscaleOPartitaIva")
    @Mapping(target = "co", source = "luogoNascita")
    @Mapping(target = "p", source = "provinciaNascita")
    @Mapping(target = "na", source = "nazioneNascita") // temporaneo
    @Mapping(target = "d", source = "dataNascita", qualifiedByName = "XMLGregorianCalendarConvert")
    @Mapping(target = "RSD", source = "denominazione")
    @Mapping(target = "FN", source = "forzaNome")
    @Mapping(target = "FC", source = "forzaCodiceFiscale")
    @Mapping(target = "FCo", source = "forzaComune")
    @Mapping(target = "NR", source = "numeroRea")
    @Mapping(target = "PC", source = "provinciaCCIAA")
    @interface DittaIndividualeDTOMappings {
    }
    
    @DittaIndividualeDTOMappings
    com.***.cmp.cgw.model.reportpersona.CAURequest.DI toDI(DittaIndividualeDTO source)
    
    @DittaIndividualeDTOMappings
    com.***.cmp.cgw.model.reportimpresa.CAURequest.DI toDI(DittaIndividualeDTO source);
    

    Note that your annotation needs the correct retention and target. I've used CLASS retention because it's not necessary to access the annotation at runtime; it's also what MapStruct uses itself. For the target I've used METHOD because only methods should get the mapping, and ANNOTATION_TYPE so you can use it in other annotations as well.