Search code examples
javamodelmapper

How to map multiple fields into one destination field using modelmapper


How to map/merge multiple fields into one field? Like concatenate a firstname and lastname to the destination fullname?

public class ModelMapperConfigTest {

    @Test
    public void should_validate() {
        new ModelMapperConfig().modelMapper().validate();
    }

    @Data
    public static class Person {
        private String firstname;
        private String lastname;
    }

    @Data
    public static class PersonDto {
        private String firstname;
        private String lastname;
        private String fullname;
    }

    // Test data

    @Test
    public void should_map_multiple_fields_into_one() {

        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

        // TODO: Configure modelmapper to merge the two fields

        // test that all fields are mapped
        modelMapper.validate();

        // test that the age is calculated
        Person person = new Person();
        person.setFirstname("Marilyn");
        person.setLastname("Monroe");
        PersonDto personDto = modelMapper.map(person, PersonDto.class);
        assertEquals(personDto.fullname, "Marilyn Monroe");
    }

    // This method should be used for mapping. In real, this could be a service call
    private String generateFullname(String firstname, String lastname) {
        return firstname + " " + lastname;
    }
}

Solution

  • You can use a Converter within a PropertyMap for this.

    Just configure your mapper like this:

    @Test
    public void should_map_multiple_fields_into_one() {
    
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
    
        modelMapper.createTypeMap(Person.class, PersonDto.class)
                .addMappings(
                        new PropertyMap<Person, PersonDto>() {
                            @Override
                            protected void configure() {
                                // define a converter that takes the whole "person"
                                using(ctx -> generateFullname(
                                        ((Person) ctx.getSource()).getFirstname(),
                                        ((Person) ctx.getSource()).getLastname())
                                )
                                // Map the compliete source here
                                .map(source, destination.getFullname());
                            }
                        });
    
        // test that all fields are mapped
        modelMapper.validate();
    
        // test that the age is calculated
        Person person = new Person();
        person.setFirstname("Marilyn");
        person.setLastname("Monroe");
        PersonDto personDto = modelMapper.map(person, PersonDto.class);
        assertEquals(personDto.fullname, "Marilyn Monroe");
    }
    
    // This method should be used for mapping. In real, this could be a service call
    private String generateFullname(String firstname, String lastname) {
        return firstname + " " + lastname;
    }