Mapping hierarchical objects to flat objects

In this post under MapStruct, I will show with example how to map hierarchical objects properties to flat object.

In all my previous posts under MapStruct, the source object didn’t compose another object. In other words, there was no object hierarchy.

In this post I will use a source object which has a hierarchy as shown below

Person

package package8;

public class Person {
    private String name;
    private int age;
    private Address address;

    //Removed getter and setter for code brevity
}

The “Address” class structure is as shown below

Address

package package8;

public class Address {
    private String addressLine1;
    private String addressLine2;

    //Removed getter and setter for code brevity
}

The destination object to which we will map is as shown below. It is a flat object

PersonDTO

package package8;

public class PersonDTO {
    private String name;
    private int age;
    private String addressLine1;
    private String addressLine2;

    //Removed getter and setter for code brevity

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(this.getName()).append(":");
        stringBuilder.append(this.getAge()).append(":");
        stringBuilder.append(this.addressLine1).append(":");
        stringBuilder.append(this.addressLine2);
        return stringBuilder.toString();
    }
}

The property names in source and destination object are same. But the source object is a hierarchical object.

The properties “addressLine1” and “addressLine2” on the source side is at different level when compared to destination object, where as other properties are at the same level.

So we have to explicitly inform MapStruct to map “Person.Address.addressLine1” to “PersonDTO.addressLine1” and “Person.Address.addressLine2” to “PersonDTO.addressLine2”.

In other words we need to have mapping information in the Mapper interface for these two properties.

Except these two, the others properties are at the same level, so we don’t need to mention mapping information explicitly for them using “@Mapping” annotation.

So our mapper interface should be like this

PersonMapper

package package8;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface PersonMapper {
    @Mapping(target = "addressLine1", source = "address.addressLine1")
    @Mapping(target = "addressLine2", source = "address.addressLine2")
    public PersonDTO getDTOFromModel(Person person);
}

We can define the above mapper interface in another short way using dot operator as shown below

Modified PersonMapper

1  package package8;
2  
3  import org.mapstruct.Mapper;
4  import org.mapstruct.Mapping;
5  
6  @Mapper
7  public interface PersonMapper {
8      @Mapping(target = ".", source = "address")
9      public PersonDTO getDTOFromModel(Person person);
10 }

So instead of having two “@Mapping” annotation for those two properties, we can have just one “@Mapping” annotation using the dot operator as shown at line 8.

In this way we can map a hierarchical object to a flat object.

Leave a comment