These examples demonstrate the flattening of a complex object model to a more simple model.

Example 1

Consider the following complex object model:

// Assume getters and setters on each class

public class Order {
  Customer customer;
  Address shippingAddress;
  Address billingAddress;

public class Customer {
  String name;

public class Address {
  String street;
  String city;

We may wish to flatten Order to a single object:

public class OrderDTO {
  String customerName;
  String shippingStreetAddress;
  String shippingCity;
  String billingStreetAddress;
  String billingCity;

  // Assume getters and setters

Assuming we have an order object we’d like to map to an OrderDTO, performing the mapping is simple:

ModelMapper modelMapper = new ModelMapper();
OrderDTO dto = modelMapper.map(order, OrderDTO.class);

We can assert that the values were mapped as expected:

assert dto.getCustomerName().equals(order.getCustomer().getName());
assert dto.getShippingStreetAddress().equals(order.getShippingAddress().getStreet());
assert dto.getShippingCity().equals(order.getShippingAddress().getCity());
assert dto.getBillingStreetAddress().equals(order.getBillingAddress().getStreet());
assert dto.getBillingCity().equals(order.getBillingAddress().getCity());

Example 2

Consider the following source object model:

// Assume getters and setters on each class

public class Person {
  Address address;

public class Address {
  String street;
  String city;

We may wish to flatten Person to the following object:

public class PersonDTO {
  String street;
  String city;

  // Assume getters and setters

With the default (Standard) matching strategy, Person.address.street will not match PersonDTO.street and Person.address.city will not match PersonDTO.city since the expected address token is not present on the destination side. To solve this we have two options:

Option 1: Create a PropertyMap

A PropertyMap allows us to create explicit mappings for street and city between the source and destination types:

PropertyMap<Person, PersonDTO> personMap = new PropertyMap<Person, PersonDTO>() {
  protected void configure() {
    map(source.getAddress().city, destination.city);


Option 2: Use the Loose Matching Strategy

While the default Standard matching strategy will not match source and destination properties that are missing a name token, the Loose matching strategy will match properties so long as the last destination property name in the hierarchy is matched. In this case the last destination property name tokens are street and city which we can expect a match for since they are present on the source side.

Configuring the Loose matching strategy to be used is simple:



After loading a PropertyMap or setting the Loose matching strategy, we can perform the map operation and assert that our results are as expected:

PersonDTO dto = modelMapper.map(person, PersonDTO.class);

assert dto.getStreet().equals(person.getAddress().getStreet());
assert dto.getCity().equals(person.getAddress().getCity());