spring-bootkotlinmapstruct

Kotlin - Mapstruct - @AfterMapping can only be applied to an implemented class


I am currently working on a mapstruct mapping on Kotlin, which has some relationship that uses Spring boot repository and services to get the object for further processing. However, I was not able to implement @AfterMapping.

@Mapper(componentModel = "spring")
interface Objectmapper {

  @Mappings(
    Mapping(source = "aCode", target = "a.code"),
    Mapping(source = "bCode", target = "b.code")
  )
  fun convertFormDtoToEntity(
    dto: ObjectFormDto,
    @Context aRepo: ARepository,
    @Context bService: BService
  ): Object

  @AfterMapping
  fun afterMappingFormDtoToEntity(
    dto: ObjectFormDto,
    @Context aRepo: ARepository,
    @Context bService: BService,
    @MappingTarget object: Object
  ){
    object.a = aRepo.findByA(object.a.code)
    object.b = bService.getB(object.b.code)
  }
}

My goal is to implement the afterMappingFormDtoToEntity() after the mapping on convertFormToEntity() is done, but I was not able to finish the kaptKotlin job and returned the error

error: @AfterMapping can only be applied to an implemented class
    public abstract void afterMappingFormDtoToEntity(@org.jetbrains.annotations.NotNull()...

My current mapstruct version is "1.5.2.Final", with kapt version "1.6.10", the following kapt settings in build.gradle.kts

kapt {
    arguments {
        arg("mapstruct.unmappedTargetPolicy", "IGNORE")
    }
    keepJavacAnnotationProcessors = true
}

Solution

  • It was solve by changing the mapper type

    from interface Objectmapper to abstract class ObjectMapper and convert all the methods to abstract except the @AfterMapping method

    The detail is written in my Medium blog post: https://3lexw.medium.com/how-to-use-mapstruct-in-kotlin-spring-with-injection-spring-services-and-repositories-5c3f468ee261