In multi-tier applications there is often a need for mapping between two data models. In this article you can read about comparing two mapping libraries:
- Dozer (http://dozer.sourceforge.net/) – popular library, where mapping is configured by XML files
- MapStruct (http://mapstruct.org/) – library, which is used for example in JHipster generator
The most common use case is coping data from entity objects to DTO objects usually used in service REST/SOAP.
Dozer | MapStruct | |
Description |
Mapping rules are defined in XML files, which are then loaded during application runtime. Dozer is using reflection mechanism for mapping. |
Mapping rules are defined in Java files, mostly in annotations. Based on this rules MapStruct generates Java classes, which are then used for mapping. |
Speed | Dozer uses reflection mechanism for mapping, which means it is slower than MapStruct. In example (link) it is mapped 1 000 000 objects. On my notebook it takes about 16 seconds. |
MapStruct invoke methods of classes, which were generated before compilation. Thanks to that it works faster than Dozer. In example (link) it is mapped 1 000 000 objects. On my notebook it takes about 3 seconds. |
MapStruct is about 500% faster than Dozer. | ||
Security |
When you make a mistake in XML that contains mapping rules you will know about it only during invoking mapping (runtime error). | When you make a mistake in property name, you will know about it during compilation. Thanks that application will be more reliable. |
Immutable objects | Dozer can access private properties (by reflection). It makes possible to map immutable objects which haven’t setters. It requires that immutable object has a constructor without parameters and in mapping files you should add attribute is-accessible="true" to destination fields. |
Unfortunately MapStruct hasn’t ability to map immutable objects. There is an open issue about that. |
Debugging | Mapping rules are defined mostly in XML files. During application runtime that files are loaded. Thus debugging mapping process is difficult – you have to set breakpoints in Dozer classes. | You can set breakpoint in classes, which was generated during compilation. Thanks that you can easily determine which classes are used for mapping and debug them. |
Popularity (as at the date 23.03.2016) |
Creation date: 04.06.2005 Stackoverflow: 1610 postów Github: https://github.com/DozerMapper/dozer Last release date: 22.04.2014 |
Creation date: 22.05.2012 Stackoverflow: 108 postów Github: https://github.com/mapstruct/mapstruct Last release date: 16.03.2016 |
Additional advantages |
|
I’ve prepared a small application, which does the same mapping using Dozer and MapStruct libraries. You can easily notice the difference in speed.
https://github.com/speedlog/mapping-tools-performance
Dozer also has a Java API, so that makes a part of your arguments against Dozer invalid. Sure, you still have to list the properties as strings, but you also have to do that if you use MapStruct. MapStructs expression language actually has the same issue tbh, it also uses strings, so if you rename any class you’ll have an issue.
An advantage of Dozer over MapStruct is that it’s more mature, and due to its usage of reflection it doesn’t require an additional build step and it has no issue mapping immutable properties.
Firstly, thanks for comment.
Dozer has a Javi API but it’s not safe – when you make a mistake in property name you will know about it during runtime. It’s opposite to MapStruct – when you make a mistake in property name (or in expression language) you will know about it during compilation.
Dozer is more mature but it’s not developed (last release 22/04/2014).
I partly agree with you about mapping immutable objects. Mapstruct can’t do this automatic – you can write mapping method and explicitly run constructor of immutable object with values from source object. Of course then you don’t need MapStruct and can do this in vanilla java.
Dozer can access directly to private properties but:
– it requires constructor with no argument
– it requires to add is-accessible=”true” for each property of immutable object
– you can’t use wildcard mappings (because you must set is-accessible flag)
Summary – both libraries are working. You must choose technology depending on your needs.
I’ll add information about mapping immutable objects in table above.