Convert Entity To DTO In Spring REST API

Learn How to convert Entity to a DTO and Convert DTO to an Entity in a Java Spring REST API, using a manual way as well as by using Model Mapper.

Overview

Entities represent the persistence model of an application and they are always internal to the application. On the other hand, DTOs (Data Transfer Objects) represent the models which the application exposes with the outside world. Having an entity based Object relational mapping framework (ORM), we can have plain java beans represented as entities. Thus, the entities and the DTOs may look similar.

However, as a better programming practice, we should not expose the internal persistence models to the outside worlds. Which means, the controllers should should always interact using with Data Transfer Objects (DTOs), while the repositories or the Data Access Objects (DAOs) should interact with entities. Having this, both the external representation of the model or a persistent model can change independently. However, this also means that the service layer should to the conversion between DTO and Entities.

Also, having a dedicated service layer keeps the Controllers and DAOs detached. However, if your controllers directly interacts with repositories or DAOs then either of them can take care of the Entity to DTO conversions.

In this article we cover Converting an Entity to a DTO and Converting a DTO to an Entity using a manual way or by using Model Mapper library. If you are looking mapping Lists of a different types using Model Mapper, read Mapping Lists of different elements types using Model Mapper.

Entity and DTO Classes

For the purpose of the examples, consider we have the Entity and DTO classes as shown next.

Entity Class

@Entity @Data public class Student { private String studentId; private String firstName; private String lastName; private int year; }
Code language: Java (java)

DTO Class

@Data public class StudentDto { private String studentId; private String firstName; private String lastName; private int year; }
Code language: Java (java)

In the coming sections, we will use these classes in examples.

Covert using Constructor

A DTO class can have a constructor, that instantiates itself using the provided entity instance. Alternatively, an entity class can have a constructor that accepts a DTO type argument.

@Data public class StudentDto { private String studentId; private String firstName; private String lastName; private int year; public StudentDto(Student entity) { this.studentId = entity.getStudentId(); this.firstName = entity.getFirstName(); this.lastName = entity.getLastName(); this.year = entity.getYear(); } }
Code language: Java (java)

Having the constructor based approach, we can convert an Entity to DTO like this.

Student student = repository.findAllById("123L"); StudentDto studentDto = new StudentDto(student);
Code language: Java (java)

Convert Using a Conversion Method

Also, an entity or a DTO can transform themselves into the other types by providing a conversion method.

@Data public class StudentDto { private String studentId; private String firstName; private String lastName; private int year; public Student toEntity() { Student entity = new Student(); entity.setStudentId(this.studentId); entity.setFirstName(this.firstName); entity.setLastName(this.lastName); entity.setYear(this.year); return entity; } }
Code language: Java (java)

The conversion method can be used to convert a DTO instance into an entity.

repository.save(studentDto.toEntity());
Code language: Java (java)

Convert Using a Dedicated Convertor

Alternatively, we can create a dedicated convertor class, that can do the conversion in both ways.

StudentMapper class

public class StudentMapper { public StudentDto toDto(Student entity) { StudentDto dto = new StudentDto(); dto.setStudentId(entity.getStudentId()); dto.setFirstName(entity.getFirstName()); dto.setLastName(entity.getLastName()); dto.setYear(entity.getYear()); return dto; } public Student toEntity(StudentDto dto) { Student entity = new Student(); entity.setStudentId(dto.getStudentId()); entity.setFirstName(dto.getFirstName()); entity.setLastName(dto.getLastName()); entity.setYear(dto.getYear()); return entity; } }
Code language: Java (java)

Let’s test this class. Next, test cases use TestNG framework.

public class StudentMapperTest { @Test public void testToEntity() { StudentDto dto = new StudentDto("123", "Jon", "Snow", 2450); StudentMapper mapper = new StudentMapper(); Student entity = mapper.toEntity(dto); assertEquals(entity.getStudentId(), dto.getStudentId()); assertEquals(entity.getFirstName(), dto.getFirstName()); assertEquals(entity.getLastName(), dto.getLastName()); assertEquals(entity.getYear(), dto.getYear()); } @Test public void testToDto() { Student entity = new Student("123", "Jon", "Snow", 2450); StudentMapper mapper = new StudentMapper(); StudentDto dto = mapper.toDto(entity); assertEquals(dto.getStudentId(), entity.getStudentId()); assertEquals(dto.getFirstName(), entity.getFirstName()); assertEquals(dto.getLastName(), entity.getLastName()); assertEquals(dto.getYear(), entity.getYear()); } }
Code language: Java (java)

Using Model Mapper Library

The manual ways of conversions are good when our beans are small. However, when we have large beans, or a large number of DTO and Entity pairs the manual way is time consuming. In order to avoid that, we can use Model Mapper library that uses reflections to convert between classes having same fields. Thus, we can use model mapper to convert entity to dto or dto to entities.

First, we need to add model mapper dependency.

<dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>{version}</version> </dependency>
Code language: HTML, XML (xml)

Next, we can create a @Bean factory method to create ModelMapper instance. This way, the model mapper instance will be available for injection on the application level.

@Bean public ModelMapper modelMapper(){ return new ModelMapper(); }
Code language: Java (java)

In order to do the conversions, we can use map() method where we need to pass source instance and the target type.

Next is an example of using Model Mapper to convert an Entity to DTO.

StudentDto dto = modelMapper.map(entity, StudentDto.class);
Code language: Java (java)

Similarly, next is an example of converting a DTO to Entity.

Student entity = modelMapper.map(dto, Student.class);
Code language: Java (java)

Next, we will write some unit tests to confirm the model mapper works correctly.

public class StudentModelMapperTest { private ModelMapper modelMapper = new ModelMapper(); @Test public void testModelMapperToEntity() { StudentDto dto = new StudentDto("123", "Jon", "Snow", 2450); Student entity = modelMapper.map(dto, Student.class); assertEquals(entity.getStudentId(), dto.getStudentId()); assertEquals(entity.getFirstName(), dto.getFirstName()); assertEquals(entity.getLastName(), dto.getLastName()); assertEquals(entity.getYear(), dto.getYear()); } @Test public void testModelMapperToDto() { Student entity = new Student("123", "Jon", "Snow", 2450); StudentDto dto = modelMapper.map(entity, StudentDto.class); assertEquals(dto.getStudentId(), entity.getStudentId()); assertEquals(dto.getFirstName(), entity.getFirstName()); assertEquals(dto.getLastName(), entity.getLastName()); assertEquals(dto.getYear(), entity.getYear()); } }
Code language: Java (java)

Summary

In this tutorial we learnt a several ways of Converting Entities to DTOs as well as Converting DTOs to Entities. Out of the many possible ways, this tutorial covered all the important ways of conversions. We learned Entity to DTO Conversion by vice versa by conversion using Constructor argument, using conversion method, using a dedicated convertor class, and finally by using Model Mapper Library.

For more on Spring and Spring Boot, please visit Spring Tutorials.