3

I have two classes. Model:

@Data
public class ExampleModel {
    private String someField;
    private String fieldInModel;
}

and DTO:

@Data
public class ExampleDto {
    private String someField;
    private String fieldInDto;
}

I want to configure simple mapper (with a different field name):

@Mapper(componentModel = "spring")
public interface ExampleMapper {

    @Mapping(target = "fieldInModel", source = "fieldInDto")
    ExampleModel mapToExample(ExampleDto exampleDto);
}

My project is a simple Spring Initializr where I add configuration for Lombok and MapStruct:

...
    <properties>
        <java.version>11</java.version>
        <mapstruct.version>1.4.1.Final</mapstruct.version>
        <lombok.version>1.18.16</lombok.version>
    </properties>

    <dependencies>
        ...
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <release>11</release>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

When I try to build it I get an error:

No property named "fieldInDto" exists in source parameter(s). Did you mean "null"?

Logs:

$ mvn clean package
...
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project demo: Compilation failure
[ERROR] /path/src/main/java/com/example/demo/ExampleMapper.java:[9,48] No property named "fieldInDto" exists in source parameter(s). Did you mean "null"?

$ java --version
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)

$ mvn -v
Apache Maven 3.5.0
Java version: 11.0.8, vendor: AdoptOpenJDK
Java home: /usr/lib/jvm/adoptopenjdk-11-hotspot-amd64
mkczyk
  • 2,460
  • 2
  • 25
  • 40

2 Answers2

11

I was able to reproduce the exact same error on my local machine, it has to do with the fact that you are using lombok alongside the Mapstruct to try and generate the mappings before your lombok classes have been generated.

A way to solve this was in the plugin to ensure that the lombok came before the mapstruct

<annotationProcessorPaths>
    <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </path>
    <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.4.1.Final</version>
    </path>
</annotationProcessorPaths>

It would seem the <annotationProcessorPaths> takes into consideration the order of the paths.

Note: if you are using the latest intellij do not forget to import after updating the order else you will get the same error

mpho mahase
  • 136
  • 5
  • Order in official MapStruct example is first `mapstruct` and second `lombok`: https://github.com/mapstruct/mapstruct-examples/blob/master/mapstruct-lombok/pom.xml (the same in tutorials eg. https://www.baeldung.com/mapstruct#Conclusion) But changing of order actually helps (with Lombok 1.18.16). With Lombok 1.18.10 order doesn't matter: https://stackoverflow.com/a/64737057/2442133 I tested only with `mvn clean package` for eliminating possible issues with IntelliJ. – mkczyk Nov 08 '20 at 10:58
  • 1
    @mapho mahase, this works for me! Thank you. – Heril Muratovic Mar 06 '21 at 21:28
0

It works with handwritten getters/setters.

I've changed Lombok version from:

<lombok.version>1.18.16</lombok.version>

to older:

<lombok.version>1.18.10</lombok.version>

And it works.

Edit: I've opened an issue on GitHub: https://github.com/mapstruct/mapstruct/issues/2271

mkczyk
  • 2,460
  • 2
  • 25
  • 40