Entity-DTO Mapping
Stop writing dto.setName(entity.getName()). MapStruct does it for you.
The Movie Subtitle Translation Analogy:
Imagine a Telugu movie being released globally. You don’t hire a human to sit in the theater and manually translate every dialogue into English on a whiteboard. That’s slow and prone to errors. Instead, you use a translation software that takes the Telugu script and automatically generates an English subtitle file.
MapStruct is that translation software for Java objects. You tell it “Map UserEntity to UserResponseDTO”, and at compile-time, it generates the Java code to copy the matching fields automatically.
- MapStruct: A code-generation tool. You create an interface, and MapStruct generates the implementation class during Maven compilation.
- @Mapper: Marks the interface as a MapStruct mapper.
- Matching Fields: MapStruct automatically maps fields that have the exact same name and data type (e.g.,
String namemaps toString name).
<!-- pom.xml Dependencies -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency><!-- pom.xml Build Plugins -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>package com.devinhyderabad;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
// componentModel = "spring" makes this a Spring Bean
@Mapper(componentModel = "spring")
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
// MapStruct generates the code to copy fields from Entity to DTO
UserResponseDTO toDto(UserEntity entity);
// MapStruct can also map DTO to Entity (for POST requests)
UserEntity toEntity(UserResponseDTO dto);
}package com.devinhyderabad;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper; // Injected by Spring
public UserService(UserRepository userRepository, UserMapper userMapper) {
this.userRepository = userRepository;
this.userMapper = userMapper;
}
public UserResponseDTO getUser(Long id) {
UserEntity entity = userRepository.findById(id).orElseThrow();
// The magic line! No manual dto.setName(entity.getName())
return userMapper.toDto(entity);
}
}Interview Question: “What is the difference between MapStruct and ModelMapper?”
Answer: ModelMapper uses Java Reflection at runtime to copy fields. This is slower but requires zero setup. MapStruct generates plain Java code at compile-time. Because it is just normal Java code executing at runtime, it is exponentially faster than ModelMapper and catches typos at compile time.
Enterprise Note: MapStruct and Lombok often fight over the annotation processor. To make them work together, you must declare the Lombok annotation processor (lombok-mapstruct-binding) inside the maven-compiler-plugin configuration in your pom.xml.
Key Takeaways
- ✅ MapStruct generates Entity-to-DTO mapping code at compile-time
- ✅ @Mapper(componentModel = "spring") makes it a Spring Bean
- ✅ MapStruct is faster than ModelMapper (no runtime reflection)
- ✅ MapStruct + Lombok need careful pom.xml annotation processor configuration
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login