Skip to content

Ignore default and static methods in @MapperConfig #3296

@dirkniblick

Description

@dirkniblick

Expected behavior

I have added an @AfterMapping method to a @MapperConfig interface:

@MapperConfig(
        componentModel = "spring",
        unmappedTargetPolicy = ReportingPolicy.IGNORE,
        uses = CommonMapper.class
)
public interface CommonMapperConfig<P extends CommonPayload, E extends CommonEntity> extends CommonMapper<P, E> {

    @AfterMapping
    default void afterMapping(@MappingTarget E entity, P payload) {
        if (entity.getNumber() > 0) {
            entity.setPositive(true);
        }
    }
}

Actual behavior

However, the code throws this when compiling:

C:\dev\env\experiment\cloned\mapstruct-aftermapping\src\main\java\com\example\mapstruct\mapper\CommonMapperConfig.java:21: error: @AfterMapping can only be applied to an implemented method.
    default void afterMapping(@MappingTarget E entity, P payload) {
                 ^

Steps to reproduce the problem

My example code is stored here on GitHub. If I remove the @AfterMapping method, the code compiles and generates a mapper.

At first I thought I was crazy for remembering being able to do this before, with the effect being that the method would be available to all of the extended mappers. But, if I change the version of Mapstruct from 1.5.5.Final to 1.4.2.Final, this works:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-06-01T10:04:02-0500",
    comments = "version: 1.4.2.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.0.jar, environment: Java 17.0.2 (Oracle Corporation)"
)
@Component
public class SpecificMapperImpl implements SpecificMapper {

    @Override
    public SpecificPayload toPayload(SpecificEntity entity) {
        if ( entity == null ) {
            return null;
        }

        SpecificPayload specificPayload = new SpecificPayload();

        specificPayload.setNumber( entity.getNumber() );
        specificPayload.setName( entity.getName() );

        return specificPayload;
    }

    @Override
    public SpecificEntity toNewEntity(SpecificPayload payload) {
        if ( payload == null ) {
            return null;
        }

        SpecificEntity specificEntity = new SpecificEntity();

        specificEntity.setNumber( payload.getNumber() );
        specificEntity.setName( payload.getName() );

        afterMapping( specificEntity, payload );

        return specificEntity;
    }

    @Override
    public SpecificEntity toUpdatedEntity(SpecificPayload payload, SpecificEntity entity, EntityContext context) {
        if ( payload == null ) {
            return null;
        }

        entity.setNumber( payload.getNumber() );
        entity.setName( payload.getName() );

        afterMapping( entity, payload );

        return entity;
    }
}

I changed versions to 1.5.0.Final and the compiler complains again. Is this illegal now?

MapStruct Version

1.5.5.Final

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions