Search code examples
javamodelmapper

ModelMapper reverse map from a destination field onto itself


Is there a way ModelMapper can reverse map a value already set using PropertyMap again to another field in destination? In other words, I have a computed value and the same has to be set on two fields using PropertyMap, computation changes the value everytime and cannot be invoked twice using(converter).


Solution

  • Introduction

    Let's consider the following versions as the current versions:

    • ModelMapper: 3.1.0.

    It seems that by the «ModelMapper» library design:

    • There is no way to «reuse» the converted source value to set multiple destination property values.

    Possible solution

    A post-converter may be used to copy a value from one destination property to another.

    Draft example program

    pom.xml file

    <dependency>
        <groupId>org.modelmapper</groupId>
        <artifactId>modelmapper</artifactId>
        <version>3.1.0</version>
    </dependency>
    

    Customer class

    class Customer {
        private String fullName;
    
        public String getFullName() {
            return fullName;
        }
    
        public void setFullName(final String fullName) {
            this.fullName = fullName;
        }
    }
    

    CustomerDTO class

    import java.util.StringJoiner;
    
    class CustomerDTO {
        private String fullName;
        private String copyOfFullName;
    
        public String getFullName() {
            return fullName;
        }
    
        public void setFullName(final String fullName) {
            this.fullName = fullName;
        }
    
        public String getCopyOfFullName() {
            return copyOfFullName;
        }
    
        public void setCopyOfFullName(final String copyOfFullName) {
            this.copyOfFullName = copyOfFullName;
        }
    
        @Override
        public String toString() {
            return new StringJoiner(", ", CustomerDTO.class.getSimpleName() + "[", "]")
                .add("fullName='" + fullName + "'")
                .add("copyOfFullName='" + copyOfFullName + "'")
                .toString();
        }
    }
    

    Program class

    import org.modelmapper.Converter;
    import org.modelmapper.ModelMapper;
    
    public final class Program {
        public static void main(final String[] args) {
            final Customer customer = new Customer();
            customer.setFullName("Full name");
    
            final ModelMapper modelMapper = new ModelMapper();
    
            final Converter<Customer, CustomerDTO> customerConverter = context -> {
                final CustomerDTO destination = context.getDestination();
                // NOTE: Copying the value of the full name property to another property.
                destination.setCopyOfFullName(destination.getFullName());
                return destination;
            };
            modelMapper.typeMap(
                Customer.class, CustomerDTO.class
            ).addMapping(
                Customer::getFullName, CustomerDTO::setFullName
            ).setPostConverter(customerConverter);
    
            modelMapper.validate();
    
            final CustomerDTO customerDTO = modelMapper.map(customer, CustomerDTO.class);
            System.out.println(customerDTO);
        }
    }
    

    Output

    CustomerDTO[fullName='Full name', copyOfFullName='Full name']
    

    Additional references