Conversion of DTO to entity and vice-versa
This is an old question with accepted answer but thought to update it with easy way of doing it using model-mapper API.
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>0.7.4</version>
</dependency>
Using this API, you avoid manual setter & getters as explained in accepted answer.
In my opinion, both conversions should happen at controller with the help of private utility methods and using Java8 stream's map ( if a Collection of DTOs is exchanged ) like illustrated in this article.
It should happen at controller because DTOs are meant to be exclusive transfer objects. I don't take my DTOs further way down.
You code your service & data access layers on entities and convert DTOs to entities before calling service methods & convert entities to DTOs before returning response from controller.
I prefer this approach because entities rarely change and data can be added / removed from DTOs as desired.
Detailed model mapper configuration and rules are described here
I can recommend to use mapstruct library:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.2.0.Final</version>
</dependency>
For example, if you have such an entity:
public class Entity {
private Integer status;
private String someString;
private Date startDate;
private Date endDate;
// SKIPPED
And DTO:
public class Dto {
private Boolean status;
private String someString;
private Long startDate;
private Long endDate;
// SKIPPED
Then the transformation can be done in the service layer by this way:
@Service
public class SomeServiceImpl implements SomeService {
@Autowired
SomeDao someDao;
@Autowired
SomeMapper someMapper;
public Dto getSomething(SomeRequest request) throws SomeException {
return someDao.getSomething(request.getSomeData())
.map(SomeMapper::mapEntityToDto)
.orElseThrow(() -> new SomeException("..."));
}
Mapper can be represented as follows:
@Mapper
public interface SomeMapper {
@Mappings(
{@Mapping(target = "entity",
expression = "java(entity.getStatus() == 1 ? Boolean.TRUE : Boolean.FALSE)"),
@Mapping(target = "endDate", source = "endDate"),
@Mapping(target = "startDate", source = "startDate")
})
Dto mapEntityToDto(Entity entity);
}
I suggest another approach without extra dependency:
import org.springframework.beans.BeanUtils
...
BeanUtils.copyProperties(sourceObject, targetObject);
Can be used to convert DTO to entity, or vice-versa, if they have same property types and names.
If you want to ignore some fields, just add them after the targetObject
.
BeanUtils.copyProperties(sourceObj, targetObj, "propertyToIgnoreA", "propertyToIgnoreB", "propertyToIgnoreC");
Source: http://appsdeveloperblog.com/dto-to-entity-and-entity-to-dto-conversion/
I think this is the cleanest way. Remember to check the Javadoc for caveats!