hs.hsadmin.ng/doc/adr/2022-08-08.object-mapping.md

109 lines
2.8 KiB
Markdown
Raw Normal View History

# Object Mapping
**Status:**
- [x] proposed by Michael Hönnig
- [ ] accepted by (Participants)
- [ ] rejected by (Participants)
- [ ] superseded by (superseding ADR)
## Context and Problem Statement
Since we are using the *API first*-approach,
thus generating Java interfaces and model classes from an OpenAPI specification,
we cannot use the JPA-entities anymore at the API level,
not even if the data fields are 100% identical.
Therefore, we need some kind of mapping strategy.
### Technical Background
Java does not support duck-typing and therefore, objects of different classes have to be converted to each other, even if all data fields are identical.
In our case, the database query is usually the slowest part of handling a request.
Therefore, for the mapper, ease of use is more important than performance,
at least as long as the mapping part does not take more than 10% of the total request.
## Considered Options
* specific programmatic conversion
* using the *MapStruct* library
* using the *ModelMapper* library
* Dozer, last update from 2014 + vulnerabilities => skipped
* Orika, last update from 2019 + vulnerabilities => skipped
* JMapper
### specific programmatic conversion
In this solution, we would write own code to convert the objects.
This usually means 3 converters for each entity/resource pair:
- entity -> resource
- resource -> entity
- list of entities -> list of resources
#### Advantages
Very flexible and fast.
#### Disadvantages
Huge amounts of bloat code.
### using the *MapStruct* library
See https://mapstruct.org/.
#### Advantages
- Most popular mapping library in the Java-world.
- Actively maintained, last release 1.5.2 from Jun 18, 2022.
- very fast (see [^1])
#### Disadvantages
- Needs interface declarations with annotations.
- Looks like it causes still too much bloat code for our purposes.
### using the *ModelMapper* library
See http://modelmapper.org/.
#### Advantages
- 1:1 mappings just need a simple method call without any bloat-code.
- Actively maintained, last release 3.1.0 from Mar 08, 2022.
#### Disadvantages
- could not find any, will give it a try
### using the *JMapper* library
See https://jmapper-framework.github.io/jmapper-core/.
#### Advantages
- Supports annotation-based and programmatic mapping exceptions.
- Actively maintained, last release 1.6.3 from May 27, 2022.
- very fast (see [^1])
#### Disadvantages
- needs a separate mapper instance for each mapping pair
- cannot map collections (needs `stream().map(...).collect(toList())` or similar)
## Decision Outcome
We chose the option **"using the *ModelMapper* library"** because it has an acceptable performance without any bloat code.
If it turns out to be too slow after all, "using the *JMapper* library" seems to be a good alternative.
[^1]: https://www.baeldung.com/java-performance-mapping-frameworks