Skip to main content
Blog Post

Using @AfterMapping with Mapstruct, Interfaces, and Lombok Builders

When using interfaces to define mapping and POJOs annotated with Lombok’s Builder, the signature for afterMapping needs to match the entry point of the mapper, with the additional parameter of the ...

Mike Cain
Using @AfterMapping with Mapstruct, Interfaces, and Lombok Builders

TLDR

When using interfaces to define mapping and POJOs annotated with Lombok’s Builder, the signature for afterMapping needs to match the entry point of the mapper, with the additional parameter of the mapping target’s builder.

The Problem

While working at a client, there was a somewhat complex task to map data from the legacy system to the greenfield system. The requirement was to update two target fields depending on another source field’s value.  Being somewhat new to Mapstruct, but not search engines, I came across the @AfterMapping capability and I felt this was the way to go.  The examples I found were not working for me because the afterMapping method was never called.  That is, until I discovered the following solution:

Let’s say you have SourceClassA with some fields and a list of SourceClassB.  Note that we use Lombok.

Here is our TargetClass:

The task is to map every SourceClassA and SourceClassB to one TargetClass (i.e. if an instance of SourceClassA has a list of 10 SourceClassBs, then there would be 10 TargetClasses).  In addition to the standard mapping, we need to change the values of two fields on the target class if a field on the source class has a specific value.  Just to make it more fun, we also need to map the target field D to the combination of field A and B from SourceClassB.

The Solution

Given that, the mapper would look like so:

Notice that the method signature for afterMapping matches the entry point for mapping, with the addition of @MappingTarget TargetClass.TargetClassBuilder builder.  Without this, the MapStruct will not be able to call the afterMapping method. 

The Proof

Here is a handy JUnit test for proof that fields A and B are changed when field B is greater than 10:

The example above is somewhat contrived and my code for the client was much nicer, but hopefully this will help in case of this complex mapping scenario!