Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@AfterMapping is not called from @Mapper interface

Tags:

java

mapstruct

I'm having trouble using Mapstruct.

I am using a @Mapper annotated interface with @AfterMapping inside like follow:

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ConfiguracionReautorizacionMapper {

    ConfiguracionReautorizacionDTO toConfiguracionReautorizacionDTO(final ConfiguracionReautorizacion configuracionReautorizacion);

    ConfiguracionReautorizacion toConfiguracionReautorizacion(final ConfiguracionReautorizacionDTO configuracionReautorizacionDTO);

    @AfterMapping
    default void fillServiciosAsociados(@MappingTarget final ConfiguracionReautorizacionDTO configuracionReautorizacionDTO, final ConfiguracionReautorizacion configuracionReautorizacion) {
        configuracionReautorizacionDTO.setTieneRolesOServiciosAsociados(!(CollectionUtils.isEmpty(configuracionReautorizacion.getRolesAplicacionEdesk()) && CollectionUtils.isEmpty(configuracionReautorizacion.getRolesAplicacionEdesk())));
    }

}

The mapper works perfectly but the @AfterMappingmethod is never called. I read other post that shows examples using abstract class instead of interface.

Is using abstract class mandatory for use @AfterMapping annotation?

like image 275
Jose A. Matarán Avatar asked Nov 25 '19 09:11

Jose A. Matarán


Video Answer


2 Answers

You can't pass the object (that is assumed to be immutable). You should pass the builder.. like this:

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ConfiguracionReautorizacionMapper {

    ConfiguracionReautorizacionDTO toConfiguracionReautorizacionDTO(final ConfiguracionReautorizacion configuracionReautorizacion);

    ConfiguracionReautorizacion toConfiguracionReautorizacion(final ConfiguracionReautorizacionDTO configuracionReautorizacionDTO);

    @AfterMapping
    default void fillServiciosAsociados(@MappingTarget final ConfiguracionReautorizacionDTO.Builder configuracionReautorizacionDTO, final ConfiguracionReautorizacion configuracionReautorizacion) {
        configuracionReautorizacionDTO.setTieneRolesOServiciosAsociados(!(CollectionUtils.isEmpty(configuracionReautorizacion.getRolesAplicacionEdesk()) && CollectionUtils.isEmpty(configuracionReautorizacion.getRolesAplicacionEdesk())));
    }

}

Checkout out MapStruct issue 1556.. You can also disable builders from 1.3.1 onwards

like image 68
Sjaak Avatar answered Sep 28 '22 07:09

Sjaak


When you are using Lombok builder and mapstruct together. @AfterMapping is not much useful though you pass a Builder object, since we can't retrieve the processed values. Instead I have used the custom method in my mapper to resolve this issue.

@Mapping(target ="field", expression = "java(customMethod(obj))")

this solved my use case, hope it helps others too.

like image 38
raji Avatar answered Sep 28 '22 07:09

raji