DTO to Entity and Entity to DTO Conversion.

Posted By : Piyush Kumar Shrivastwa | 03-Dec-2020

In the RESTful web service application, we may have to perform the DTO to entity and entity to DTO conversion. Where DTO stands for data transfer object which is a simple plain java object that contains setter and getter methods to access those properties.

There are some libraries that we can use to do the Entity to DTO conversion or vice versa.

Goal:

We have an Entity class as shown here.

public class Car {

    private long id;
    private String make;
    private int numOfSeats;
    private Date releaseDate;
    private Engine engine;
    
    //getters & setters

}
public class Engine {
    private String type;
    
    //getters & setters
}

We have below corresponding DTO classes.

public class CarDto {

    private long id;
    private String make;
    private int numOfSeats;
    private Date releaseDate;
    private EngineDto engineDto;
    
    //getters & setters
}
public class EngineDto {
    private String type;

    //getters & setters
}

Entity Object Creation:

let's create a simple car entity instance.

//create Car entity
Car car = new Car();
car.setId(1);
car.setMake("Honda");
car.setNumOfSeats(4);
Date date = Date.from(LocalDate.of(2010, 10, 10).atStartOfDay(ZoneId.systemDefault()).toInstant());
car.setReleaseDate(date);
//create Engine enity
Engine engine = new Engine();
engine.setType("V6");
car.setEngine(engine);

// we use mapping libraries here

1. By Using BeanUtils class of spring-boot to Copy Properties from Entity to DTO.

The use of BeanUtils is very simple. While copying properties from a source Java object to a targeted Java object a simple static method is used.

//BeanUtils.copyProperties(sourceObject, targetObject);

BeanUtils.copyProperties(car, CarDto);

a. BeanUtils – Ignore Certain Properties

//BeanUtils.copyProperties(sourceObject, targetObject,ignoreparameter1,ignoreparameter2);

BeanUtils.copyProperties(car, CarDto, "make", "releaseDate");

2. Model Mapper.

we have to include the below maven dependency.

<dependency>
  <groupId>org.modelmapper</groupId>
  <artifactId>modelmapper</artifactId>
  <version>2.3.0</version>
</dependency>

Map this DTO with an entity like.

ModelMapper modelMapper = new ModelMapper();

CarDto carDto = modelMapper.map(car, CarDto.class);

3. MapStruct.

MapStruct is simple to use. However, it is not as easy as the above-mentioned libs.

Include the below maven dependency.

<dependency>
  <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
  <version>1.3.0.Final</version>
</dependency>

Add this below maven plugin.

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.5.1</version>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
    <annotationProcessorPaths>
      <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.3.0.Final</version>
      </path>
    </annotationProcessorPaths>
  </configuration>
</plugin>

Create a CarMapper interface to do the mapping. If the source and target properties are different, we need to add the @Mapping with source and target property names
MapStruct automatically detects the child beans.

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface CarMapper {

    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );

    @Mapping(source = "engine", target = "engineDto")
    CarDto toDto(Car car);

    EngineDto toDto(Engine engine);

}

We can parse entity to DTO by calling :

CarDto carDto = CarMapper.INSTANCE.toDto(car);

MapStruct creates this class at compile time using the Mapper interface we have created.

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2019-09-01T02:17:45+0000",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 12.0.2 (Oracle Corporation)"
)
public class CarMapperImpl implements CarMapper {

    @Override
    public CarDto toDto(Car car) {
        if ( car == null ) {
            return null;
        }
        CarDto carDto = new CarDto();
        carDto.setEngineDto( toDto( car.getEngine() ) );
        carDto.setId( car.getId() );
        carDto.setMake( car.getMake() );
        carDto.setNumOfSeats( car.getNumOfSeats() );
        carDto.setReleaseDate( car.getReleaseDate() );
        return carDto;
    }

    @Override
    public EngineDto toDto(Engine engine) {
        if ( engine == null ) {
            return null;
        }
        EngineDto engineDto = new EngineDto();
        engineDto.setType( engine.getType() );
        return engineDto;
    }
}

4. Manual Conversion

Let's ignore all the libraries and do the Entity to DTO conversion manually ourselves.

EngineDto engineDto = new EngineDto();
  engineDto.setType(car.getEngine().getType());
  CarDto carDto = new CarDto();
  carDto.setId(car.getId());
  carDto.setMake(car.getMake());
  carDto.setNumOfSeats(car.getNumOfSeats());
  carDto.setReleaseDate(car.getReleaseDate());
  carDto.setEngineDto(engineDto);
  System.out.println(carDto);

There are many libraries out there to do this conversion. I picked just a few for comparison. Among the 3 I had chosen, MapStruct seems to do the job exceptionally well. It is because it does not use run time java APIs. Instead, the code for doing the above mapping is getting generated at compile time. In fact, the code it creates is very close to what we have had for the manual conversion. So the performance of MapStruct is very close to manual conversion.

Thanks.

 

We, at Oodles Technologies, provide full-scale SaaS app development services to build scalable, responsive, and quality-driven web and mobile applications. Contact us for technical assistance or drop us a line at [email protected] for more detail. 

About Author

Author Image
Piyush Kumar Shrivastwa

He is hardworking and honest about his work and is familiar with Spring framework, etc. He has keen interest in learning more about new technologies.

Request for Proposal

Name is required

Comment is required

Sending message..