Search code examples
javamapstructobject-object-mapping

Nested Mapping using MapStruct


class Identifier {
    private long id;
    private String type;
    private List<Status> statuses;
}     

class Customer {
    private Identifier identifier;
}

class CustomerProfile {
    private Customer customer;
}

class CustomerIdentifierDO {
    private long id;
}

class CustomeDO {
    private CustomerIdentiferDO custID;

}

class CustomerProfileDO {
    private String category;
    private List<Status> custStatuses;
    private CustomeDO customer;
}

@Mapper
public interface CustomerProfileMapper {
    CustomerProfile toCustomerProfile(CustomerProfileDO profileDO) ;  
    Customer   toCustomer(CustomerDO customerDO);
    Identifier toIdentifier(CustomerIdentifierDO identifierDO);

}

Everything works fine till this. Now I want to map custStatuses, category of CustomerProfileDO class to statuses and type of Identifier class. I've no idea how to supply CustomerProfileDO object to toIdentifier mapping method, so that I can include the mapping there itself. I tried following

@Mappings({
     @Mapping(target = "customer.identifier.type", source = "category")
})
CustomerProfile   toCustomerProfile(CustomerProfileDO profileDO) ; 

But this nested mapping is overriding all the mapping config of below method. That should not happen.

toIdentifer(CustomerIdentifierDO identifierDO)

Is there any way to achieve this?


Solution

  • Currently MapStruct can pass source parameters to single methods. In order to achieve what you are looking for (without using nested target types you would need to use something like @AfterMapping. It can look like:

    @Mapper
    public interface CustomerProfileMapper {
        CustomerProfile toCustomerProfile(CustomerProfileDO profileDO) ;  
        Customer   toCustomer(CustomerDO customerDO);
        Identifier toIdentifier(CustomerIdentifierDO identifierDO);
    
        @AfterMapping
        default void afterMapping(@MappingTarget CustomerProfile profile, CustomerProfieDO profileDO) {
            Identifier identifier = profile.getCustomer().getIdentifier();
            identifier.setStatus(profileDO.setStatus());
            identifier.setType(profileDO.setCategory());
        }    
    }