Today we will see how to implement a ModelMapper that allows us, for example, to transform an object with many properties into a smaller object with fewer properties. This transformation can be useful when we need leaner objects, perhaps in a list, or when we want to expose only some properties of an object, leaving the others hidden in logic.
Mapping data between objects can be a tedious and error-prone task, especially in larger applications with complex object models. Thankfully, libraries like ModelMapper come to the rescue, offering a simple and efficient way to automate this process. This article dives into this library, exploring its capabilities and showcasing its usage with detailed Java code examples.
What is ModelMapper?
Is an open-source Java library designed to simplify object-to-object mapping. It leverages conventions and reflection to automatically map fields between source and destination objects, reducing the need for manual boilerplate code. This makes it a valuable tool for developers working with various data models, including DTOs, view models, and entities.
Key features
- Automatic mapping: ModelMapper analyzes field names and types to automatically map corresponding fields between objects.
- Convention-based: Common naming conventions (e.g., getter methods, matching field names) are used for mapping, making it intuitive and easy to use.
- Customizable: You can fine-tune the mapping behavior through property mappings, converters, and configuration options.
- Supports basic types and collections: ModelMapper handles primitive types, collections, and nested objects.
Import the library we need. To install ModelMapper with Maven, add the following dependency to your pom.xml
file:
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.1.0</version>
</dependency>
Simple mapping example
Here’s an example demonstrating how to map a User
object to a UserDto
using ModelMapper:
// Source object
public class User {
private String name;
private int age;
// Getters and setters...
}
// Destination object
public class UserDto {
private String fullName;
private String ageGroup;
// Getters and setters...
}
public class Main {
public static void main(String[] args) {
ModelMapper mapper = new ModelMapper();
User user = new User("John Doe", 30);
UserDto userDto = mapper.map(user, UserDto.class);
System.out.println(userDto.getFullName()); // John Doe
System.out.println(userDto.getAgeGroup()); // null (needs customization)
}
}
In this example, ModelMapper automatically maps the name
field from User
to the fullName
field in UserDto
. However, the ageGroup
field requires customization, which we’ll explore next.
Customization options
ModelMapper offers various ways to customize mapping behavior:
- Property Mapping: This allows you to define specific mappings for fields with different names or custom logic.
PropertyMap<User, UserDto> map = new PropertyMap<User, UserDto>();
map.configure(source -> source.getAge(), (source, destination) -> destination.setAgeGroup(source > 25 ? "Adult" : "Youth"));
mapper.addMappings(map);
- Converters: Use custom converters for complex transformations or non-standard data types.
- Configuration Options: Modify global behavior through options like ignoring null values or skipping missing fields.
Use ModelMapper in Spring Boot
We have 2 objects:
class FullDTO {
long id;
String title;
String author;
String email;
String password;
String webSite;
int hiddenInformation;
boolean isForAdmin;
// assume getters and setters
}
class LightDTO {
long id;
String title;
String author;
// assume getters and setters
}
In the class that needs mapping we can create a mapping method and use it ( mapToLight()
):
import org.modelmapper.ModelMapper;
class UsingModelMapper {
@Autowired private ModelMapper modelMapper;
public LightDTO mapToLight(FullDTO fullDTO) {
return modelMapper.map(aSource, LightDTO.class);
}
}
Now we need a ModelMapper
bean to be wired for statically import it in all our application.
To configure ModelMapper in the application:
// MyBEConfig.java
import org.modelmapper.ModelMapper;
@Configuration
@EnableWebMvc
public class MyApplicationConfig implements WebMvcConfigurer {
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
Benefits of using ModelMapper
- Reduced code: Simplifies object mapping, eliminating repetitive boilerplate code.
- Improved maintainability: Clean and concise mapping logic enhances code readability and maintainability.
- Flexibility: Customizable options cater to complex mapping scenarios.
- Widely used: Popular library with a large community and extensive documentation.
Conclusion
ModelMapper is a valuable tool for streamlining object mapping in Java applications. Its ease of use, automatic mapping capabilities, and customization options make it a popular choice for developers of all levels. Whether you’re working with simple data models or complex object hierarchies, ModelMapper can significantly reduce your development time and effort while maintaining code clarity and flexibility.
That’s all for now.
Try it at home!