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!