With this tutorial, I am going to share with you how to convert one Java Model Class into another. You might need to use it when converting a DTO(Data Transfer Object) to an Entity bean and back from Entity bean to a DTO. And also when converting a DTO to a REST Model Object which will then be returned back as an entity object in the body of HTTP Response.
For mapping of one very simple Model class or to another I often use the BeanUtils.copyProperties(sourceObject, targetObject); but if one of the Model classes contains Inner objects and more intelligent mapping needs to be done, then a ModelMapper class will do a very good job.
Add ModelMapper to Your Project
You can download ModelMapper and add to your project as a library or if you are a Maven user then add the following dependency to a pom.xml file of your project.
<dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>2.3.0</version> </dependency>
DTO and Entity Classes
Let’s assume we have the following DTO and Entity classes:
UserDto class:
package com.appsdeveloperblog.app.ws.shared.dto; import java.io.Serializable; import java.util.List; public class UserDto implements Serializable{ private static final long serialVersionUID = 6835192601898364280L; private long id; private String userId; private String firstName; private String lastName; private String email; private String password; private String encryptedPassword; private String emailVerificationToken; private Boolean emailVerificationStatus = false; private List<AddressDTO> addresses; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEncryptedPassword() { return encryptedPassword; } public void setEncryptedPassword(String encryptedPassword) { this.encryptedPassword = encryptedPassword; } public String getEmailVerificationToken() { return emailVerificationToken; } public void setEmailVerificationToken(String emailVerificationToken) { this.emailVerificationToken = emailVerificationToken; } public Boolean getEmailVerificationStatus() { return emailVerificationStatus; } public void setEmailVerificationStatus(Boolean emailVerificationStatus) { this.emailVerificationStatus = emailVerificationStatus; } public List<AddressDTO> getAddresses() { return addresses; } public void setAddresses(List<AddressDTO> addresses) { this.addresses = addresses; } }
AddressEntity class:
package com.appsdeveloperblog.app.ws.io.entity; import java.io.Serializable; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name = "users") public class UserEntity implements Serializable { private static final long serialVersionUID = 4865903039190150223L; @Id @GeneratedValue private long id; @Column(nullable = false) private String userId; @Column(length = 50, nullable = false) private String firstName; @Column(length = 50, nullable = false) private String lastName; @Column(length = 100, nullable = false) private String email; @Column(nullable = false) private String encryptedPassword; private String emailVerificationToken; @Column(nullable = false, columnDefinition = "boolean default false") private Boolean emailVerificationStatus; @OneToMany(mappedBy = "userDetails", cascade=CascadeType.ALL) private List<AddressEntity> addresses; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getEmailVerificationToken() { return emailVerificationToken; } public void setEmailVerificationToken(String emailVerificationToken) { this.emailVerificationToken = emailVerificationToken; } public Boolean getEmailVerificationStatus() { return emailVerificationStatus; } public void setEmailVerificationStatus(Boolean emailVerificationStatus) { this.emailVerificationStatus = emailVerificationStatus; } public String getEncryptedPassword() { return encryptedPassword; } public void setEncryptedPassword(String encryptedPassword) { this.encryptedPassword = encryptedPassword; } public List<AddressEntity> getAddresses() { return addresses; } public void setAddresses(List<AddressEntity> addresses) { this.addresses = addresses; } }
Use ModelMapper to Convert DTO to an Entity
To convert one Model class like a DTO object to another Model class like an Entity Java bean, for example, we can use ModelMapper class the following way:
import org.modelmapper.ModelMapper; ... ModelMapper modelMapper = new ModelMapper(); UserEntity userEntity = modelMapper.map(userDto, UserEntity.class); ...
Use ModelMapper to Convert Entity to a DTO
Let’s assume we have a useRepository object which persists userEntity into a database. After user details are stored we want to convert a userEntity object to a DTO and return it as a return value.
import org.modelmapper.ModelMapper; ... ModelMapper modelMapper = new ModelMapper(); UserEntity storedUserDetails = userRepository.save(userEntity); UserDto returnValue = modelMapper.map(storedUserDetails, UserDto.class); ...
Flattening of Two Objects into a Single One
You can also use ModelMapper to copy properties from a complex object into a new object with a simpler structure.
For example, let’s assume we have the following complex User class which contains a single address object:
UserDto class:
public class UserDto { String firstName firstName; String firstName lastName; String email; AddressDto shippingAddress; ... }
AddressDto class:
public class AddressDto { private long id; private String addressId; private String city; private String country; private String streetAddress; private String postalCode; ... }
We can flatten the above two classes into a single class OrderDto:
OrderDto class:
public class OrderDto { private long id; private String firstName firstName; private String firstName lastName; private String email; private String addressId; private String city; private String country; private String streetAddress; private String postalCode; ... }
Flatten two objects: UserDto and an AndressDto into a new object OrderDto:
ModelMapper modelMapper = new ModelMapper(); OrderDTO orderDto = modelMapper.map(userDto, OrderDTO.class);
Map List of Objects
We can also map a List of one Java objects into a List of another. For example, Let’s assume we need to convert a List of Entity objects into a list of DTO objects.
// Get list of User DTO objects from a database Pageable pageableRequest = PageRequest.of(page, limit); Page<UserEntity> users = userRepository.findAll(pageableRequest); List<UserEntity> userEntities = users.getContent(); // Create Conversion Type Type listType = new TypeToken<List<UserDto>>() {}.getType(); // Convert List of Entity objects to a List of DTOs objects List<UserDto> returnValue = new ModelMapper().map(users, listType); return returnValue;
I hope this short tutorial was helpful to you. If you are interested to learn more about building RESTful Web Services with Java and Spring Framework, please checkout out the following with many more tutorials: RESTful Web Services with Spring MVC. And if you enjoy learning by watching video lessons, then have a look at the below list of Video courses:
how to copy List of UserEntity to UserDto ?
in my example except List which is mentioned above all other properties are getting copied to UserDto but not List,
how to solve this problem?
Can you please shade some light on it?
Thanks..
Have you tried using TypeToken?
// Create Conversion Type
Type listType = new TypeToken
>() {}.getType();
// Convert List of Entity objects to a List of DTOs objects returnValue = new ModelMapper().map(users, listType);
List
Hello Sergey,
Good Day@
I have a class StatesEntity with a field private List cities;
and a class CityEntity that has field private String cityName;
The StatesDto class and CityDto class have same members as mentioned above.
I have written a method that maps a list of StatesEntity objects to list of StatesDto, using modelmapper.
public List getListofStatesDto() {
logger.info(“Mapping list of StatesEntity Objects to list of StatesDto Objects”);
List statesEntityList = stateRepository.findAll(Sort.by(Sort.Direction.ASC, “stateName”));
Type listType = new TypeToken<List>() {
}.getType();
List statesDtoList = modelMapper.map(statesEntityList, listType);
return statesDtoList;
}
However the statesDtoList continues to have a List of Cities that has CityEntity Objects.
What could be the best way to map a list of CityEntities to list of CityDtos in such a scenario?
I have also written methods to map a list of CityEntities to list of CityDtos,but not sure how to implement it here.
Thanks in Advance