ATTENTION: You are on the develop
branch.
This has been renamed to master
.
The develop
branch will not be maintained anymore.
It is only left here to avoid broken links to existing content.
Please update links to point to the master
branch.
For details look at issue #320.
For decoupling you sometimes need to create separate objects (beans) for a different view. E.g. for an external service you will use a transfer-object instead of the persistence entity so internal changes to the entity do not implicitly change or break the service.
Therefore you have the need to map similar objects what creates a copy. This also has the benefit that modifications to the copy have no side-effect on the original source object. However, to implement such mapping code by hand is very tedious and error-prone (if new properties are added to beans but not to mapping code):
public UserEto mapUser(UserEntity source) {
UserEto target = new UserEto();
target.setUsername(source.getUsername());
target.setEmail(source.getEmail());
...
return target;
}
Therefore we are using a BeanMapper
for this purpose that makes our lives a lot easier.
To get access to the BeanMapper
we have to use either of below dependency in our POM:
We started with dozer.sourceforge.net/[dozer] in devon4j and still support it. However, we now recommend orika (for new projects) as it is much faster (see Performance of Java Mapping Frameworks).
<dependency>
<groupId>com.devonfw.java</groupId>
<artifactId>devon4j-beanmapping-orika</artifactId>
</dependency>
or
<dependency>
<groupId>com.devonfw.java</groupId>
<artifactId>devon4j-beanmapping-dozer</artifactId>
</dependency>
The BeanMapper
implementation is based on an existing open-source bean mapping framework.
In case of Dozer the mapping is configured src/main/resources/config/app/common/dozer-mapping.xml
.
See the my-thai-star dozer-mapping.xml as an example.
Important is that you configure all your custom datatypes as <copy-by-reference>
tags and have the mapping from PersistenceEntity
(ApplicationPersistenceEntity
) to AbstractEto
configured properly:
<mapping type="one-way">
<class-a>com.devonfw.module.basic.common.api.entity.PersistenceEntity</class-a>
<class-b>com.devonfw.module.basic.common.api.to.AbstractEto</class-b>
<field custom-converter="com.devonfw.module.beanmapping.common.impl.dozer.IdentityConverter">
<a>this</a>
<b is-accessible="true">persistentEntity</b>
</field>
</mapping>
Then we can get the BeanMapper
via dependency-injection what we typically already provide by an abstract base class (e.g. AbstractUc
). Now we can solve our problem very easy:
...
UserEntity resultEntity = ...;
...
return getBeanMapper().map(resultEntity, UserEto.class);
There is also additional support for mapping entire collections.