Search code examples
lombokmapstruct

MapStruct is unable to use Lombok's builder with custom setterPrefix


I started integrating MapStruct with an existing Spring Boot application (that uses Lombok).

The problem is that most classes are following the builder pattern (implemented with Lombok), but they have a custom setterPrefix. I can see that MapStruct tells me that fields withXXX are not mapped, but I would like to know if there is a solution for this.

This is the setup:

plugins {
  id("io.freefair.lombok") // Notice how I'm using Lombok, so shifting dependencies is not an option
}

dependencies {
  annotationProcessor("org.mapstruct:mapstruct-processor:1.4.2.Final")
  annotationProcessor("org.projectlombok:lombok-mapstruct-binding:0.2.0")

  implementation("org.mapstruct:mapstruct:1.4.2.Final")

  ...
}

java {
  consistentResolution {
    useCompileClasspathVersions()
  }
  sourceCompatibility = JavaVersion.VERSION_11
  targetCompatibility = JavaVersion.VERSION_11
}

lombok {
  config["lombok.addLombokGeneratedAnnotation"] = "true"
  config["lombok.log.fieldIsStatic"] = "false"
  config["lombok.log.fieldName"] = "logger"
  version = "1.18.18"
}
@Setter
@Builder(setterPrefix = "with")
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PUBLIC, force = true)
public final class Model {
  @Getter(onMethod = @__(@ColumnName("model_id")))
  private Long id;

  ...
}
@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
interface ModelMapper {
  Model valueFrom(CreateModelCommand command);
}

The only solutions I've found so far is:

  • To declare a @Mapping for every field; e.g.: @Mapping(source = "fieldName", target = "withFieldName") ― quite the challenge!
  • To just remove the custom setterPrefix from Lombok's @Builder annotation

Solution

  • When you have non standard property names then the best approach is to use a Custom Accessor Naming Strategy.

    With it you can define how to extract the property name from a method.