DTO to Entity Mapping with Different Field Types in Spring Boot

Last updated on October 22nd, 2024

DTO to Entity mapping is a common requirement in Spring Boot applications. When we map DTO to Entity and vice versa, our DTO and Entity have fields with different data types, such as converting the String field of DTO to the LocalDate field of Entity and vice versa. We can do DTO to Entity Mapping with different field types in Spring Boot using Manual Mapping, MapStruct, and ModelMapper. In this topic, we will learn how to DTO to Entity Mapping with different field types in Spring Boot in various approaches.

DTO to Entity Mapping with different field types in Spring Boot

Approaches of DTO to Entity Mapping with Different Field Types

There are three approaches for Mapping DTO to Entity with different field types are:

  1. Using Manual Mapping
  2. Using MapStruct
  3. Using ModelMapper

Scenerio DTO to Entity Mapping with Different Field Types

Let’s assume String and boolean type fields in the DTO class and LocalDate and int type fields in the Entity class. In this scenario, we need to map String to LocalDate, boolean to int and vice-versa. For this, we will use Manual Mapping, MapStruct and ModelMapper.

Using Manual Mapping

We can explicitly map String to LocalDate, boolean to int and vice versa by creating logic in some utility class.

Example

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

public class WebSeriesMapper {

static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy");

// Convert DTO to Entity

    public static WebSeries dtoToEntity(WebSeriesDTO dto) {

    WebSeries webSeries = new WebSeries();

    webSeries.setName(dto.getName());

        // Convert String to LocalDateTime

        if (dto.getReleasingDate() != null && !dto.getReleasingDate().isEmpty()) {

        webSeries.setReleasingDate(LocalDate.parse(dto.getReleasingDate(), formatter));

        }

        //Convert boolean to int (true -> 1, false -> 0)

        webSeries.setStatus(dto.isStatus() ? 1 : 0);

        return webSeries;

    }

// Convert Entity to DTO

public static WebSeriesDTO entityToDto(WebSeries webSeries){

WebSeriesDTO dto = new WebSeriesDTO();

dto.setId(webSeries.getId());

dto.setName(webSeries.getName());

// Convert LocalDateTime to String

if (webSeries.getReleasingDate() != null) {

dto.setReleasingDate(webSeries.getReleasingDate().format(formatter));

}

// Convert int to boolean (1 -> true for active, 0 -> false for inactive)

dto.setStatus(webSeries.getStatus()==1 ? true:false);

return dto;

}

}
  • We convert a String in the DTO to LocalDate in the Entity to using DateTimeFormatter.
  • We convert a boolean in the DTO to int in the Entity (false to 0, true to 1).
  • Similarly, we handle the reverse conversion when mapping from Entity to DTO.

In our Service class we can use this WebSeriesMapper class to convert DTO to Entity with different field types and also convert Entity to DTO.

Example

import java.util.ArrayList;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

import com.springjava.repository.WebSeriesRepo;

import com.springjava.utility.WebSeriesMapper;

@Service

public class WebSeriesServiceImpl implements WebSeriesService {

@Autowired

private WebSeriesRepo webSeriesRepo;

@Override

public void saveAll(List<WebSeriesDTO> dtoList) {

List<WebSeries> webSeriesList = new ArrayList<>();

for (WebSeriesDTO dto : dtoList) {

//Use Manual conversion for DTO to Entity with different data type

WebSeries webSeries = WebSeriesMapper.dtoToEntity(dto);

webSeriesList.add(webSeries);

}

webSeriesRepo.saveAll(webSeriesList);

}

@Override

public List<WebSeriesDTO> getAll() {

List<WebSeriesDTO> dtoList = new ArrayList<>();

       for(WebSeries webSeries: webSeriesRepo.findAll()) {

        //Use Manual conversion for Entity to DTO with different data type

        WebSeriesDTO dto=WebSeriesMapper.entityToDto(webSeries);

        dtoList.add(dto);

       }

return dtoList;

}

}

Using MapStruct

If we are using MapStruct to convert DTO to Entity mapping with different field types and vice versa then we must add the MapStruct library and create an interface with @Mapper annotation.

Add the MapStruct dependencies to pom.xml

<!-- MapStruct dependency -->
   <dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct</artifactId>
       <version>1.6.2</version>
   </dependency>

   <!-- For MapStruct processor-->
   <dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct-processor</artifactId>
       <version>1.6.2</version>
       <scope>provided</scope>
   </dependency>

Creating an Interface

We need to create an Interface with @Mapper annotation.

Example

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import org.mapstruct.Mapper;

import org.mapstruct.Mapping;

import org.mapstruct.Named;

import org.mapstruct.factory.Mappers;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

@Mapper

public interface WebSeriesMapStruct {

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

   DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy");

// Custom method to map int to boolean

   @Named("mapStatusToBoolean")

   default boolean mapStatusToBoolean(int status) {

       return status == 1 ? true: false;

   }

   // Custom method to map Date String to LocalDate

   @Named("mapStringToLocalDateTime")

   default LocalDate mapStringToLocalDateTime(String date) {

       return date != null ? LocalDate.parse(date, formatter) : null;

   }

   //Map Entity to DTO with custom date and status handling

   @Mapping(source = "releasingDate", target = "releasingDate", dateFormat = "d-MM-yyyy")

   @Mapping(source = "status", target = "status", qualifiedByName = "mapStatusToBoolean")

   WebSeriesDTO entityToDto(WebSeries entity);

//Map DTO to Entity with custom handling for date and status handling

   @Mapping(source = "releasingDate", target = "releasingDate", qualifiedByName = "mapStringToLocalDateTime")

@Mapping(target = "status", expression = "java(dto.isStatus() ? 1 : 0)")

WebSeries dtoToEntity(WebSeriesDTO dto);

}
  • In the above code, we used MapStruct to convert DTO to Entity with different field types and vice versa. 

In our Service class, we can use this WebSeriesMapStruct interface to convert DTO to Entity and vice versa.

Example

import java.util.ArrayList;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

import com.springjava.repository.WebSeriesRepo;

import com.springjava.utility.WebSeriesMapStruct;

@Service

public class WebSeriesServiceImpl implements WebSeriesService {

@Autowired

private WebSeriesRepo webSeriesRepo;

@Override

public void saveAll(List<WebSeriesDTO> dtoList) {

List<WebSeries> webSeriesList = new ArrayList<>();

for (WebSeriesDTO dto : dtoList)

//Use MapStruct for converting DTO to Entity with different data type

WebSeries webSeries = WebSeriesMapStruct.INSTANCE.dtoToEntity(dto);

webSeriesList.add(webSeries);

}

webSeriesRepo.saveAll(webSeriesList);

}

@Override

public List<WebSeriesDTO> getAll() {

List<WebSeriesDTO> dtoList = new ArrayList<>();

       for(WebSeries webSeries: webSeriesRepo.findAll()) {

        //Use MapStruct for converting Entity to DTO with different data type

        WebSeriesDTO dto = WebSeriesMapStruct.INSTANCE.entityToDto(webSeries);

        dtoList.add(dto);

       }

return dtoList;

}

}

Using ModelMapper

To use ModelMapper to convert DTO to Entity with different field types and vice versa, we need to add the ModelMapper library and configure ModelMapper to the Spring Boot application.

Add the ModelMapper dependency to pom.xml

<!-- ModelMapper dependency -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.2.1</version>
</dependency>

Configure the ModelMapper class

We will create a class where we configure the ModelMapper class.

Example

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import org.modelmapper.ModelMapper;

import org.modelmapper.PropertyMap;

import org.modelmapper.convention.MatchingStrategies;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

@Configuration

public class ModelMapperConfig {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy");

    @Bean

    public ModelMapper modelMapper() {

        ModelMapper modelMapper = new ModelMapper();

        // Set strict matching strategy to avoid ambiguity

        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

        // Map DTO to Entity (String date to LocalDate)

        modelMapper.addMappings(new PropertyMap<WebSeriesDTO, WebSeries>() {

            @Override

            protected void configure() {

                // Custom date mapping from String to LocalDate

                using(ctx -> LocalDate.parse(((String) ctx.getSource()), formatter))

                    .map(source.getReleasingDate(), destination.getReleasingDate());

                // Custom status mapping from boolean to int

                map(source.isStatus() ? 1 : 0, destination.getStatus());

            }

        });

        // Map Entity to DTO (LocalDate to String date)

        modelMapper.addMappings(new PropertyMap<WebSeries, WebSeriesDTO>() {

            @Override

            protected void configure() {

                // Custom date mapping from LocalDate to String

                using(ctx -> ((LocalDate) ctx.getSource()).format(formatter))

                    .map(source.getReleasingDate(), destination.getReleasingDate());

                // Custom status mapping from int to boolean

                map(source.getStatus() == 1? true:false, destination.isStatus());

            }

        });

        return modelMapper;

    }

}
  • In this class, we configured ModelMapper and converted String in the DTO to LocalDate in the Entity and boolean in the DTO to int in the Entity. We also mapped Entity to DTO with different field types.

To use this ModelMapper class in the Service class, call its map() method. 

Example

import java.util.ArrayList;

import java.util.List;

import org.modelmapper.ModelMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

import com.springjava.repository.WebSeriesRepo;

@Service

public class WebSeriesServiceImpl implements WebSeriesService {

@Autowired

private WebSeriesRepo webSeriesRepo;

@Autowired

private ModelMapper modelMapper;

@Override

public void saveAll(List<WebSeriesDTO> dtoList) {

List<WebSeries> webSeriesList = new ArrayList<>();

for (WebSeriesDTO dto : dtoList) {

//Use ModelMapper for converting DTO to Entity with different data type

WebSeries webSeries = modelMapper.map(dto, WebSeries.class);

webSeriesList.add(webSeries);

}

webSeriesRepo.saveAll(webSeriesList);

}

@Override

public List<WebSeriesDTO> getAll() {

List<WebSeriesDTO> dtoList = new ArrayList<>();

        for(WebSeries webSeries: webSeriesRepo.findAll()) {       

         //Use MapStruct for converting Entity to DTO with different data type

         WebSeriesDTO dto = modelMapper.map(webSeries, WebSeriesDTO.class);

         dtoList.add(dto);

        }

return dtoList;

}

}

Step-by-step Guide to DTO to Entity Mapping with Different Field Types

Let’s create a Spring Boot Application step-by-step guide to implement DTO to Entity Mapping with different field types. We will create an example of WebSeries saving and retrieving by converting DTO to Entity with different field types and vice versa using API endpoints through the approaches mentioned above.  

These are the following steps:

  1. Create a Spring Boot Project
  2. Setup in the IDE
  3. Configure H2 Database
  4. Create a JPA Entity
  5. Create a Repository Interface
  6. Create a DTO class
  7. Use Mapping(DTO to Entity and Entity to DTO) 
  8. Create a Service Interface
  9. Implement the Service Interface
  10. Create a Controller
  11. Run the Spring Boot Application

1. Create a Spring Boot Project

 We are creating a Spring Boot Project from the web tool Spring Initializr. By Providing details for the project and select the following Maven dependencies:

  • Spring Web
  • Spring Data JPA
  • H2 Database
  • Lombok

2. Setup in the IDE

We use Eclipse IDE to set up and configure the created Spring Boot Project. You can use other IDE to set up and configure the Spring Boot project.

Project Structure of Spring Boot

This image shows the project structure of Spring Boot in Eclipse IDE.

DTO to Entity Mapping with different field types in Spring Boot

Maven Dependency

Here is the complete maven dependencies file pom.xml for the project which will implement DTO to Entity with different field types.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.0</version>
		<relativePath />
		<!-- lookup parent from repository -->
	</parent>
	<groupId>com.springjava</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- ModelMapper dependency -->
		<dependency>
			<groupId>org.modelmapper</groupId>
			<artifactId>modelmapper</artifactId>
			<version>3.2.1</version>
		</dependency>
		<!-- MapStruct dependency -->
		<dependency>
			<groupId>org.mapstruct</groupId>
			<artifactId>mapstruct</artifactId>
			<version>1.6.2</version>
		</dependency>
		<!-- For MapStruct processor-->
		<dependency>
			<groupId>org.mapstruct</groupId>
			<artifactId>mapstruct-processor</artifactId>
			<version>1.6.2</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

3. Configure H2 Database

We are going to configure the H2 database connection in the application.properties file.

application.properties

#H2 Database Configuration
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true

4. Create a JPA Entity

Let’s create a JPA Entity class. For example, consider a WebSeries entity and use Lombok to implicitly generate setter and getter methods, a constructor, etc.

OrderDetail.java

package com.springjava.entity;

import java.time.LocalDate;

import jakarta.persistence.Entity;

import jakarta.persistence.GeneratedValue;

import jakarta.persistence.GenerationType;

import jakarta.persistence.Id;

import lombok.Data;

@Data

@Entity

public class WebSeries {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

private String name;

private LocalDate releasingDate;

private int status;

}

5. Create a Repository Interface

Create a repository interface for the WebSeries JPA Entity class that interface extends the JpaRepository interface to perform persistence operations on the order_detail database table.

OrderRepository.java

package com.springjava.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.springjava.entity.WebSeries;

public interface WebSeriesRepo extends JpaRepository<WebSeries, Long> {
}

6. Create a DTO class

We are creating a DTO class WebSeriesDTO which has different field types such as String releasingDate and boolean status from Entity class WebSeries field types such as LocalDate releasingDate and int status.

WebSeriesDTO.java

package com.springjava.dto;

import lombok.Data;

@Data

public class WebSeriesDTO {

private Long id;

private String name;

private String releasingDate;

private boolean status;

}

7. Use Mapping(DTO to Entity and Entity to DTO)

We are using Mapping(DTO to Entity and Entity to DTO) with conversion String releasingDate to LocalDate releasingDate and boolean status to int status and vice versa.

Create a Mapper Utility class 

We are creating a mapper class WebSeriesMapper for Manual Mapping(DTO to Entity and Entity to DTO).

WebSeriesMapper.java

package com.springjava.utility;

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

public class WebSeriesMapper {

static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy");

// Convert Entity to DTO

public static WebSeriesDTO entityToDto(WebSeries webSeries) {

WebSeriesDTO dto = new WebSeriesDTO();

dto.setId(webSeries.getId());

dto.setName(webSeries.getName());

// Convert LocalDateTime to String

if (webSeries.getReleasingDate() != null) {

dto.setReleasingDate(webSeries.getReleasingDate().format(formatter));

}

// Convert int to boolean (1 -> true for active, 0 -> false for inactive)

dto.setStatus(webSeries.getStatus() == 1 ? true : false);

return dto;

}

// Convert DTO to Entity

public static WebSeries dtoToEntity(WebSeriesDTO dto) {

WebSeries webSeries = new WebSeries();

webSeries.setName(dto.getName());

// Convert String to LocalDateTime

if (dto.getReleasingDate() != null && !dto.getReleasingDate().isEmpty()) {

webSeries.setReleasingDate(LocalDate.parse(dto.getReleasingDate(), formatter));

}

// Convert boolean to int (true -> 1, false -> 0)

webSeries.setStatus(dto.isStatus() ? 1 : 0);

return webSeries;

}

}

Create a Mapper Interface

We are creating a Mapper Interface WebSeriesMapStruct for mapping using MapStruct.

WebSeriesMapStruct.java

package com.springjava.utility;

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import org.mapstruct.Mapper;

import org.mapstruct.Mapping;

import org.mapstruct.Named;

import org.mapstruct.factory.Mappers;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

@Mapper

public interface WebSeriesMapStruct {

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

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy");

 // Custom method to map int to boolean

    @Named("mapStatusToBoolean")

    default boolean mapStatusToBoolean(int status) {

        return status == 1 ? true: false;

    }

    // Custom method to map Date String to LocalDate

    @Named("mapStringToLocalDateTime")

    default LocalDate mapStringToLocalDateTime(String date) {

        return date != null ? LocalDate.parse(date, formatter) : null;

    }

    //Map Entity to DTO with custom date and status handling

    @Mapping(source = "releasingDate", target = "releasingDate", dateFormat = "d-MM-yyyy")

    @Mapping(source = "status", target = "status", qualifiedByName = "mapStatusToBoolean")

    WebSeriesDTO entityToDto(WebSeries entity);

//Map DTO to Entity with custom handling for date and status handling

    @Mapping(source = "releasingDate", target = "releasingDate", qualifiedByName = "mapStringToLocalDateTime")

@Mapping(target = "status", expression = "java(dto.isStatus() ? 1 : 0)")

WebSeries dtoToEntity(WebSeriesDTO dto);

}

Configure ModelMapper class

We are creating a configuration class ModelMapperConfig with @Configuration annotation to configure the ModelMapper class with @Bean annotation to map DTO to Entity and Entity to DTO using the ModelMapper library.

ModelMapperConfig.java

package com.springjava.utility;

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import org.modelmapper.ModelMapper;

import org.modelmapper.PropertyMap;

import org.modelmapper.convention.MatchingStrategies;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

@Configuration

public class ModelMapperConfig {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy");

    @Bean

     ModelMapper modelMapper() {

        ModelMapper modelMapper = new ModelMapper();

        // Set strict matching strategy to avoid ambiguity

        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

        // Map DTO to Entity (String date to LocalDate)

        modelMapper.addMappings(new PropertyMap<WebSeriesDTO, WebSeries>() {

            @Override

            protected void configure() {

                // Custom date mapping from String to LocalDate

                using(ctx -> LocalDate.parse(((String) ctx.getSource()), formatter))

                    .map(source.getReleasingDate(), destination.getReleasingDate());

                // Custom status mapping from boolean to int

                map(source.isStatus() ? 1 : 0, destination.getStatus());

            }

        });

        // Map Entity to DTO (LocalDate to String date)

        modelMapper.addMappings(new PropertyMap<WebSeries, WebSeriesDTO>() {

            @Override

            protected void configure() {

                // Custom date mapping from LocalDate to String

                using(ctx -> ((LocalDate) ctx.getSource()).format(formatter))

                    .map(source.getReleasingDate(), destination.getReleasingDate());

                // Custom status mapping from int to boolean

                map(source.getStatus() == 1? true:false, destination.isStatus());

            }

        });

        return modelMapper;

    }

}

8. Create a Service Interface

Create a Service interface WebSeriessService with some method declaration.

WebSeriesService.java

package com.springjava.service;

import java.util.List;

import com.springjava.dto.WebSeriesDTO;

public interface WebSeriesService {

void saveAll(List<WebSeriesDTO> dtoList);

List<WebSeriesDTO> getAll();

}

9. Implement the Service Interface

Implement the WebSeriesService interface in the WebSeriesServiceImpl class. This class is annotated with @Service annotation, where we inject WebSeriesRepo to call all its methods(saveAll() and findAll()).

WebSeriesServiceImpl.java

package com.springjava.service;

import java.util.ArrayList;

import java.util.List;

import org.modelmapper.ModelMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.entity.WebSeries;

import com.springjava.repository.WebSeriesRepo;

import com.springjava.utility.WebSeriesMapStruct;

import com.springjava.utility.WebSeriesMapper;

@Service

public class WebSeriesServiceImpl implements WebSeriesService {

@Autowired

private WebSeriesRepo webSeriesRepo;

@Autowired

private ModelMapper modelMapper;

@Override

public void saveAll(List<WebSeriesDTO> dtoList) {

List<WebSeries> webSeriesList = new ArrayList<>();

for (WebSeriesDTO dto : dtoList) {

//Use Manual conversion for DTO to Entity with different data type

WebSeries webSeries = WebSeriesMapper.dtoToEntity(dto);

//Use MapStruct for converting DTO to Entity with different data type

//WebSeries webSeries = WebSeriesMapStruct.INSTANCE.dtoToEntity(dto);

//Use ModelMapper for converting DTO to Entity with different data type

//WebSeries webSeries = modelMapper.map(dto, WebSeries.class);

webSeriesList.add(webSeries);

}

webSeriesRepo.saveAll(webSeriesList);

}

@Override

public List<WebSeriesDTO> getAll() {

List<WebSeriesDTO> dtoList = new ArrayList<>();

        for(WebSeries webSeries: webSeriesRepo.findAll()) {

         //Use Manual conversion for Entity to DTO with different data type

         WebSeriesDTO dto=WebSeriesMapper.entityToDto(webSeries);

         //Use MapStruct for converting Entity to DTO with different data type

         //WebSeriesDTO dto = WebSeriesMapStruct.INSTANCE.entityToDto(webSeries);

         //Use MapStruct for converting Entity to DTO with different data type

         //WebSeriesDTO dto = modelMapper.map(webSeries, WebSeriesDTO.class);

         dtoList.add(dto);

        }

return dtoList;

}

}
  • In the above, we have called methods to map DTO to Entity and Entity to DTO with different field types using Manual Mapping, MapStruct and ModelMapper.
  • We commented on MapStruct and ModelMapper Mappings in the code. You can code the uncomment of these used mappings.

10. Create a Controller

Create a controller class WebSeriesController. This is annotated with @RestController to make this class a RestController.

WebSeriesController.java

package com.springjava.controller;

import java.util.LinkedHashMap;

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import com.springjava.dto.WebSeriesDTO;

import com.springjava.service.WebSeriesService;

@RestController

@RequestMapping("/api/webseries")

public class WebSeriesController {

@Autowired

private WebSeriesService webSeriesService;

@PostMapping("/save-all")

public ResponseEntity<?> save(@RequestBody List<WebSeriesDTO> dtoList) {

Map<String, Object> respOrder = new LinkedHashMap<String, Object>();

webSeriesService.saveAll(dtoList);

respOrder.put("status", 1);

respOrder.put("message", "Record is Saved Successfully!");

return new ResponseEntity<>(respOrder, HttpStatus.CREATED);

}

@GetMapping("/list")

public ResponseEntity<?> getAll() {

Map<String, Object> respOrder = new LinkedHashMap<String, Object>();

List<WebSeriesDTO> dtoList = webSeriesService.getAll();

if (!dtoList.isEmpty()) {

respOrder.put("status", 1);

respOrder.put("data", dtoList);

return new ResponseEntity<>(respOrder, HttpStatus.OK);

} else {

respOrder.clear();

respOrder.put("status", 0);

respOrder.put("message", "Data is not found");

return new ResponseEntity<>(respOrder, HttpStatus.NOT_FOUND);

}

}

}

11. Run the Spring Boot Application

Right-click this Spring Boot application on the DemoApplication.java, then click Run As and select Java Application.

H2 Database Console

To check the H2 database console use the URL http://localhost:[server_port]/h2-console.

JSON Array

We are creating a sample JSON Array to test the API http://localhost:8080/api/order/save-all.

[
  {
    "name": "Demo",
    "releasingDate": "30-09-2024",
    "status": true
  },
  {
    "name": "Abc",
    "releasingDate": "01-10-2024",
    "status": false
  }
]

Test the APIs on the Postman Tool

POST: http://localhost:8080/api/order/save-all

DTO to Entity Mapping with different field types in Spring Boot

GET: http://localhost:8080/api/webseries/list

DTO to Entity Mapping with different field types in Spring Boot

Conclusion

In Spring Boot, converting between DTO to Entity with different field types can be handled in various ways:

  • Manual Mapping: Explicitly converting data types using a utility class.
  • MapStruct: A compile-time code generator that simplifies mapping with annotations using the MapStruct library.
  • ModelMapper: A flexible runtime mapping tool that supports custom mappings and complex object structures using ModelMapper library.

Leave a Comment