MapStruct @MappingTarget generates an empty method
Asked Answered
B

3

5

Have a target type, formed by Lombok:

@Data
@Builder
class Target {
   private final String a;
}

and have a DTO:

@Value
@Builder
class DTO {
   private final String a;
}

Mapper:

@Mapper(componentModel = "spring")
interface Mapper {
    void update(DTO dto, @MappingTarget Target target);
}

But when I compile (saw something related to JDK 11, and yes, it is 11 in my case), the compiled method is empty:

public void update(DTO source, Target target) {
   if (source == null) {
       return;
   }
}

And this is only relevant to MappingTarget. Using regular Mapping methods of 'createFromDTO' works correctly.

MapStruct 1.3.0

Brower answered 10/10, 2019 at 14:17 Comment(0)
A
5

Maven only uses Mapstruct processor, then you need add in Maven plugin in your pom.xml, a configuration to Mapstruct works with Lombok processor.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${org.mapstruct.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${org.projectlombok.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-mapstruct-binding</artifactId>
                <version>0.1.0</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

You don't need to include final modifier. Use @Data instead @Value as previously mentioned.

In my tests, this is sufficient to Mapstruct 1.4.1.Final works with Lombok and JDK 11.

Anomalous answered 14/12, 2020 at 15:2 Comment(1)
Eventually came to similar answer (I think, a bit outdated question). But thanks.Brower
B
1

Well, it turned to be Lombok + private final.

Mapper specifically wants Lombok's @Data to be stated instead of @Value (had thought that @Builder to be of use by MapStruct), and, as a result, needed to remove final from the fields, which were needed to be updated.

Strange thing is, this was done by "google, error and try again" (plus manually cleaning the out directory from the project on every attempt, since MapStruct ignored these changes), while MapStruct never gave a warning (no flags for ignoring warnings or errors were declared).

Brower answered 10/10, 2019 at 14:48 Comment(3)
Could you please elaborate?Dichroite
just as I thought. lombok and mapstruct have a rough relationship.Dichroite
MapStruct doesn't care about any annotation from Lombok. It relies on the fact that Lombok properly exposes the methods. For this particular problem have a look at github.com/rzwitserloot/lombok/issues/1538Brythonic
M
1

I know I'm late to the party, I already have the lombok-mapstruct-binding in place, but I still had to resort to make my entity mutable by using @Data instead of @Value, as it just created the mapper bindings for explicit setters and did not use the builder after all.

This only occurred when I wanted to post-fill the entity with @MappingTarget though.

Miticide answered 26/2, 2024 at 9:4 Comment(1)
As long as this question helped somebody beside me (or not), it's fine :)Brower

© 2022 - 2025 — McMap. All rights reserved.