I'm using ModelMapper with Spring. In my controller class I'm autowiring the ModelMapper bean:
@Autowired
private ModelMapper mapper;
I want to do an explicit mapping between my model class and my DTO in my controller methods, something like:
modelMapper.addMappings(mapper -> {
mapper.map(src -> src.getBillingAddress().getStreet(),
Destination::setBillingStreet);
mapper.map(src -> src.getBillingAddress().getCity(),
Destination::setBillingCity);
});
And then use the mapper to map the classes.
My question is, is it right to add explicit mappings in every controller method call? Will object modelMapper start to grow in memory size?
Other solution is to add the mapping only one time when ModelMapper bean is created, but I don't think that putting mapping logic in a bean configuration is a good decision.
You can define a property mapping by using method references to match a source getter and destination setter. typeMap. addMapping(Source::getFirstName, Destination::setName); The source and destination types do not need to match.
ModelMapper consists of two separate processes: the matching process, where a source and destination type's properties are matched to each other, and the mapping process where matched property values are converted from a source to destination object.
When we use the starter, we just add a Gradle dependency and then autowire the ModelMapper instance in our controllers. @Controller public class TaskController { @Autowired private TaskRepository taskRepository; @Autowired private ModelMapper modelMapper; ... }
It is totally fine to setup the mapping logic in the bean configuration of ModelMapper
.
Mapping is the actual task of that class, so it should be configured when it is created.
Nevertheless, I prefer to create multiple dedicated mapper definitions, one for each type or group of related types.
Doing it this way keeps the configuration aspect separate from the actual usage of the mapper in the controllers - without creating a big pile of unrelated mapping configuration code in one class. Indeed, configuring the mapper in each controller would violate principles like DRY (don't repeat yourself) and SoC (separation of concerns).
In your case (singleton ModelMapper
) you may create @Configuration
-annotated classes for each type or group of types you want to map.
Within that class you would receive the ModelMapper
and add the type mappings.
Add your configuration code to either
ModelMapper
-receiving constructor or@PostConstruct
-annotated method which accesses an @Autowired
ModelMapper
attribute.I haven't used ModelMapper
myself yet but after peeking into its codebase I would guess that if you follow your original approach, the memory usage would not increase but you would find exceptions about duplicate mappings getting thrown.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With