Mastering Object Mapping in Spring Boot with @Mapper and @Mapping

Anil R
2 min readSep 17, 2024

--

In Spring Boot, if you’re working with data transfer objects (DTOs) or entity mapping between layers (e.g., between service and persistence layers), using a mapping framework like MapStruct can be helpful. The @Mapper and @Mapping annotations are part of MapStruct, a code generator that simplifies the process of mapping between Java objects.

Key Concepts of MapStruct:

  1. @Mapper:

This annotation is applied to an interface or abstract class. It indicates that this interface is a Mapper, and the MapStruct processor will automatically generate an implementation for it.

@Mapper
public interface UserMapper {
UserDTO toDto(User entity);
User toEntity(UserDTO dto);
}

In this example, UserMapper is a mapper interface that will map a User entity to UserDTO and vice versa.

@Mapping:

This annotation is used inside a Mapper interface when you want to explicitly define how fields in one object map to fields in another. It is used when the fields don’t have a direct match or if additional logic is required.

@Mapper
public interface UserMapper {

@Mapping(source = "name", target = "fullName")
@Mapping(source = "address.street", target = "streetName")
UserDTO toDto(User entity);

@Mapping(source = "fullName", target = "name")
@Mapping(source = "streetName", target = "address.street")
User toEntity(UserDTO dto);
}

In this case, @Mapping explicitly tells MapStruct how to map fields that don't have the same names (name to fullName and address.street to streetName).

Example Use Case:

Suppose you have the following classes:

Entity Class:

public class User {
private String name;
private Address address;
// Getters and Setters
}
public class Address {
private String street;
private String city;
// Getters and Setters
}

DTO Class:

public class UserDTO {
private String fullName;
private String streetName;
// Getters and Setters
}

Mapper Interface with MapStruct:

@Mapper
public interface UserMapper {

@Mapping(source = "name", target = "fullName")
@Mapping(source = "address.street", target = "streetName")
UserDTO toDto(User user);

@Mapping(source = "fullName", target = "name")
@Mapping(source = "streetName", target = "address.street")
User toEntity(UserDTO userDTO);
}

How it works:

  • The @Mapper tells MapStruct to create an implementation of this interface.
  • The @Mapping annotation explicitly defines how to map fields from the source object to the target object.
  • MapStruct automatically generates the code needed to map between User and UserDTO.

Configuration in Spring Boot:

  1. Add the MapStruct dependency in your pom.xml:

<dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.0.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.0.Final</version> <scope>provided</scope> </dependency> </dependencies>

  1. Enable the MapStruct processor in Spring Boot. You don’t have to do anything special for Spring Boot if you use Maven or Gradle. MapStruct automatically integrates into the build process.
  2. Inject the Mapper into your service layer using Spring’s @Autowired or constructor injection:

@Service public class UserService { private final UserMapper userMapper; @Autowired public UserService(UserMapper userMapper) { this.userMapper = userMapper; } public UserDTO getUserDto(User user) { return userMapper.toDto(user); } }

This is how @Mapper and @Mapping annotations work in Spring Boot using MapStruct for object mapping.

--

--

Anil R
Anil R

Written by Anil R

Full Stack Developer with 15 years experience.

No responses yet