Mapping Lists of different elements types using Model Mapper

Examples of Mapping between a List of Entity beans and a List of DTO in Java using ModelMapper library.

Overview

This tutorial explains how to use the ModelMapper library to map Lists of different types. Mapping Lists of different types means converting a List of one type of element to the other. In typical web-based applications, we keep Entities and DTOs separated. However, they mostly have similar fields. The takeaway from this tutorial will also help you to convert a List<Entity> to a List<DTO> and vice versa.

This tutorial is limited to converting between lists of different element types. If you are looking to Map an Entity Bean to a DTO and vice versa, please read Convert Entity To DTO In Spring REST API.

First, we will set up the ModelMapper library in our application.

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

List of Entity and List of DTO Conversion

Next are the two Java Beans we want to map in each other.

The first Java bean is the StudentDto class, the Data Transfer Object (DTO).

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

The following Java bean is the Student class which represents the Entity bean.

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

Let’s create a collection of the Entity Bean and convert it into a collection of DTOs.
Example of mapping List<Entity> to List<DTO> using model mapper.

List<Student> students = List.of(
    new Student("123", "Baristan", "Selmy", 2024),
    new Student("125", "Strong", "Belwas", 2029)
);

ModelMapper mapper = new ModelMapper();
TypeToken<List<StudentDto>> typeToken = new TypeToken<>() {
};

List<StudentDto> studentDtos = 
    mapper.map(students, typeToken.getType());Code language: Java (java)

The map() method on the modelMapper takes the source object and the target type. In our case, the type of target type is generic. Thus, we created an anonymous instance of TypeToken, providing the correct generic type argument. We used the TypeToken instance to perform the mapping.

Validate Before List Mapping

In the previous example, the source and the destination beans had precisely the same fields with the same data types. But, sometimes, the fields may contain different fields. Thus, the mapping may fail with an exception.

We can prevent that proactively with the validate() method. The method throws the ValidationException if the Entity and DTO classes’ fields are incompatible.

Validating Entity and DTO Mapping Compatibility.

ModelMapper mapper = new ModelMapper();
mapper.createTypeMap(StudentDto.class, Student.class);
mapper.validate();Code language: Java (java)

Mapping Lists Iteratively

Alternatively, instead of asking the ModelMapper to map the List of objects, we can iterate through the collection and invoke the map() method on each element of the List. By doing so, we can avoid the overhead of TypeToken.
Mapping List of Entity and List of DTO Iteratively.

List<StudentDto> dtos = new ArrayList<>();
ModelMapper mapper = new ModelMapper();
students.forEach(student -> 
    dtos.add(mapper.map(student, StudentDto.class)));Code language: Java (java)

Note that we do not have a generic type here. Thus, we can provide the target type explicitly without using TypeToken.

Summary

This quick tutorial demonstrated ways of using the ModelMapper library to convert a List of Entity beans to a List of DTO objects.

The ModelMapper smartly identifies the fields with the same name and uses reflection to map their values. It also provides a validate() method that we can use to find if the beans in the mapping are compatible with each other. For more on Java, please visit Java Tutorials.