'@AfterMapping is not called from @Mapper interface
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?
Solution 1:[1]
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
Solution 2:[2]
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.
Solution 3:[3]
As mentioned in the comments the issue is because you are likely using Lombok Builder annotation for ConfiguracionReautorizacionDTO and ConfiguracionReautorizacion and possibly any of the nested classes of these classes. AfterMapping functionality does not play well with Lombok Builder. Again Lombok generally works with MapStruct, it seems Builder annotation is a specific issue. See if you can create the classes without using Builder annotation and then AfterMapping functionality should work as expected.
Solution 4:[4]
Thanks to @Sjaak answer which is the legit answer. For my case this worked:
myAfterMapping(...,@MappingTarget MyBean.MyBeanBuilder<?, ?> myBean,...){
myBean.id(someValue);
}
MyBeanBuilder is autogenerated (@Builder).
Solution 5:[5]
This is a comment but can't fit in the comment section.
If someone is gonna use @raji's answer, you must pay attention to the name of the variable you pass to customMethod
instead of obj you must put the name of the variable in your mapper method.
for Example:
@Mapping(target ="name", expression = "java(resolveName(userModel))")
UserDTO toDTO(User userModel);
default String resolveName(final User model) {
return String.format("%s %s", model.firstName, model.lastName);
}
Solution 6:[6]
It is a bug when using Lombok#@Builder and Mapstruct@AfterMapping
Please use this situation @BeanMapping(builder = @Builder(disableBuilder = true)).
see https://github.com/mapstruct/mapstruct/issues/1556#issuecomment-1011493330
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sjaak |
| Solution 2 | raji |
| Solution 3 | Grizzled DevArch |
| Solution 4 | LovaBill |
| Solution 5 | Tarun Kolla |
| Solution 6 | Xuanyu |
