Java
Object Mapping
Java Tools
Programming
Object-Oriented

any tool for java object to object mapping?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In the world of Java development, mapping between different object models is a common task that can often become tedious and error-prone if done manually. Luckily, several libraries help automate this process by providing object-to-object mapping capabilities. One such robust tool is ModelMapper. This article delves into the usefulness of ModelMapper, its features, configuration needs, and how it simplifies the task of mapping objects.

What is ModelMapper?

ModelMapper is a Java library designed to ease the process of mapping between objects. It is particularly useful for converting between Data Transfer Objects (DTOs) and entity objects, a routine task often required in data-centric and domain-driven design (DDD) architectures. By leveraging configuration capabilities, ModelMapper minimizes boilerplate code and improves maintainability for data transformation logic.

Key Features

  • Conventions and Configurations: ModelMapper uses conventions over configurations by default, providing a set of sensible defaults that adhere to best practices. However, developers can tweak these defaults through an API for custom logic.
  • Type Safety and Linear Mapping: By providing a simple, type-safe API, ModelMapper allows direct linear mapping, making code more readable and robust.
  • Nested Mapping: ModelMapper supports automatic mapping of nested properties, which is essential for mapping complex hierarchical structures.
  • Conditional Mapping: It can handle conditional mapping scenarios based on custom logic, which can be useful for dynamic mappings.
  • Performance Optimization: ModelMapper is designed with performance in mind, able to handle large collections and objects with minimal configuration.

Configuration Basics

ModelMapper comes with a variety of configuration options. Here’s how to get started with basic configurations:

java
1ModelMapper modelMapper = new ModelMapper();
2
3// Configure strict mapping
4modelMapper.getConfiguration()
5    .setMatchingStrategy(MatchingStrategies.STRICT);
6
7// Add property mapping if field names are different
8modelMapper.typeMap(Source.class, Destination.class).addMappings(mapper -> {
9    mapper.map(Source::getSourceProperty, Destination::setDestinationProperty);
10});

In the example above, the setMatchingStrategy method sets the mapping strategy to strict, meaning both field names and types must match exactly. Custom field mappings are also demonstrated in the typeMap method.

Example of Object Mapping

Consider a scenario wherein you need to map data from an UserEntity object to a UserDTO object.

java
1// Source class
2public class UserEntity {
3    private String firstName;
4    private String lastName;
5    private String email;
6    // getters and setters
7}
8
9// Destination class
10public class UserDTO {
11    private String fullName;
12    private String email;
13
14    // custom getter to demonstrate mapped data
15    public String getFullName() {
16      return fullName;
17    }
18
19    // setters are not shown for brevity
20}
21
22// Mapping example
23ModelMapper modelMapper = new ModelMapper();
24TypeMap<UserEntity, UserDTO> typeMap = modelMapper.createTypeMap(UserEntity.class, UserDTO.class);
25
26// Configure custom property mapping
27typeMap.addMappings(mapper -> {
28    mapper.map(src -> src.getFirstName() + " " + src.getLastName(), UserDTO::setFullName);
29});
30
31UserEntity userEntity = new UserEntity();
32userEntity.setFirstName("John");
33userEntity.setLastName("Doe");
34userEntity.setEmail("[email protected]");
35
36UserDTO userDTO = modelMapper.map(userEntity, UserDTO.class);
37
38// Outputs: John Doe
39System.out.println(userDTO.getFullName());

Handling Advanced Scenarios

Lists and Collections

ModelMapper can handle mappings for collections seamlessly. Below is a demonstration:

java
1List<UserEntity> entities = List.of(userEntity1, userEntity2);
2List<UserDTO> dtos = entities.stream()
3                             .map(entity -> modelMapper.map(entity, UserDTO.class))
4                             .collect(Collectors.toList());

Conditional Mapping

java
1modelMapper.addMappings(new PropertyMap<UserEntity, UserDTO>() {
2    protected void configure() {
3        when((ctx) -> ctx.getSource() != null).map(source.getPhoneNumber(), destination.getPhoneNumber());
4    }
5});

Comparison with Other Tools

ModelMapper isn't the only tool for object mapping in Java. Others like MapStruct, Dozer, and JMapper exist. Here's a comparison of their key features:

ToolCode GenerationAnnotations RequiredPerformanceCommunity Support
ModelMapperNoNoMediumHigh
MapStructYesYesHighMedium
DozerNoNo (uses XML)LowLow
JMapperYesYesHighMedium

Conclusion

ModelMapper provides a flexible and powerful way to map objects in Java applications. Its default convention and ability to customize mappings make it a go-to choice for many developers. Whether dealing with simple attribute mappings or complex nested structures, ModelMapper offers a robust and performant solution. For high-performance scenarios or compile-time checks, alternatives like MapStruct might be considered. Nonetheless, ModelMapper remains an essential tool in a Java developer's toolkit for simplifying object transformations.


Course illustration
Course illustration

All Rights Reserved.