- • Quickstart
- • Documentation
- • Documentation DevOps
- › Spring Data
- • MongoDB
- • Spring REST
- • IntelliJ Integration
Last updated: 2021-12-10
Using MapStruct with Maven and Lombok
MapStruct is a Java library to simplify data transfer between classes and avoid writing boilerplate code. The following article will show the steps to automate the mapping between a JPA entity and a DTO in a Spring Boot application.
For our example, we use the following technologies:
- Spring Boot 2.6.7
As developers, all we need to do is provide an interface that defines the desired mapping methods. MapStruct then generates the implementing class at build time - so our initial setup is a bit more extensive.
In our pom.xml, we first need to add the dependency that will later allow us to define our mapper.
Furthermore, we need to extend the
maven-compiler-plugin to activate the code generation of MapStruct.
Lombok is our first annotation processor, followed directly by MapStruct. Another reference to
lombok-mapstruct-binding is necessary for these two libraries to work together. Without Lombok, only the
mapstruct-processor would be needed at this point.
Now let's get to the core of our example - the mapper. In our example, there is a "CarPart" entity that has a primary key, two data fields as well as a reference to a "Supplier".
Our JPA Entity example
Our DTO contains all fields of the entity with further annotations for validation when used in a
RestController. The reference to the Supplier is specified in form of the foreign key id.
Our example DTO
With these classes in place, we can now define the first version of our mapper. The "CarPartMapper" contains two methods for mapping in both directions. By annotating the interface with
@Mapper, MapStruct will parse it and provide an implementing class. With
componentModel = "spring" the class is added to Spring's application context and can be referenced later on in our service using
First version of our Mapper
The provided methods are automatically parsed by MapStruct. One parameter is the source object and the parameter with
@MappingTarget defines the target object. Without a
@MappingTarget the target object would be newly initialized; this however isn' t desired in our case. The class generated by MapStruct will automatically map all fields with the same name - in our case id, typeCode and releaseDate.
@Mapping annotation we can add special handlings for single fields. Since the id field is automatically generated by our persistence layer (
GenerationType.IDENTITY), it should not be taken from the DTO to the entity. For the reference to the Supplier we want to add a custom handling, so this field should be ignored as well.
Mapping the foreign key
Lastly, we want to handle the reference to the Supplier by adding the following two default methods to our interface:
Adding custom behaviour with @AfterMapping
By annotating them with
@AfterMapping we tell MapStruct to call the method after the initial mapping. With
@Context we can add additional parameters to the method - we use this ability here to provide the SupplierRepository. If the specified Supplier does not exist, a
404 error should be returned.
With this, our mapper is ready and can be used in our service.
Using our new Mapper for creating a CarPart
Bootify provides a free tool to create a Spring Boot application with a custom database schema and REST API. The Professional plan also provides an option for MapStruct, so the required mappers are automatically generated and added to your code base.