Home > database >  Add ModelMapper Maping from Entity Class to Dto Class with OneToMany relationship
Add ModelMapper Maping from Entity Class to Dto Class with OneToMany relationship

Time:02-04

I have that relationships (Spring Boot JPA Implementation):

One Person have multiples Addresses

One Address contains one Country

public class Person {
    
private Integer id;
private Integer name;
private Integer age;

//relations
}
  
        
public class Address {
    
private Integer id;
private Integer person_id;
private String street;
private String city;
private String country_id;
private Boolean preferred;

//relations
}
        
public class Country {
    
private Integer id;
private Integer description;

//relations

and i want return a DTO in that way

public class PersonDto {

 private Integer id;
 private Integer name;
 private Integer age;
 private String street;
 private String city;
 private Integer country //description;

but in fact i want

  1. only return preferred address of person (only can have one).
  2. Get only Country description in nested class of Address

It's possible with ModelMapper (AddMapping Strategy)

Thanks,

CodePudding user response:

One of the options is doing it with a Converter.

import org.modelmapper.Converter;
import org.modelmapper.spi.MappingContext;

public class PersonToDtoConverter implements Converter<Person, PersonDto> {

  @Override
  public PersonDto convert(MappingContext<Person, PersonDto> context) {
    Person source = context.getSource();
    PersonDto destination = context.getDestination();
    if (destination == null) {
      destination = new PersonDto();
    }
    destination.setId(source.getId());
    destination.setName(source.getName());
    destination.setAge(source.getAge());
    Address address = source.getAddresses().stream().filter(Address::getPreferred).findFirst().orElse(null);
    if (address != null) {
      destination.setStreet(address.getStreet());
      destination.setCity(address.getCity());
      destination.setCountry(address.getCountry().getDescription());
    }
    return destination;
  }
}

Then you need to register the converter with the ModelMapper instance.

import org.modelmapper.ModelMapper;

import java.util.ArrayList;
import java.util.List;

public class Mappings {

  public static void main(String[] args) {
    //setup
    Country germany = new Country();
    germany.setId(1);
    germany.setDescription(11);
    Address address = new Address();
    address.setCountry(germany);
    address.setCity("Munich");
    address.setId(1);
    address.setCountry_id("DE");
    address.setStreet("some street");
    address.setPreferred(true);
    address.setPerson_id(1);
    Person person = new Person();
    person.setId(1);
    person.setAge(29);
    person.setName(111);
    List<Address> addresses = new ArrayList<>();
    addresses.add(address);
    person.setAddresses(addresses);

    //convert
    ModelMapper modelMapper = new ModelMapper();
    modelMapper.addConverter(new PersonToDtoConverter());
    PersonDto personDto = modelMapper.map(person, PersonDto.class);
    System.out.println(personDto);
  }
}

CodePudding user response:

You can manually define mappings containing arbitrary logic, e.g.:

ModelMapper mm = new ModelMapper();
mm.typeMap(Person.class, PersonDto.class).addMappings(mapper -> {
            mapper.map(
              person -> { // the source object
                for(Address address : person.getAddresses()){
                  if(address.isPreferred() && address.getCountry() != null)
                    return address.getCountry.getDescription();
                }
                return null; // or default country if no address is preferred / etc...
              },
              PersonDto::setCountry); // corresponding setter of the DTO
        });
 
var myDto = mm.map(myPerson, PersonDto.class);

http://modelmapper.org/getting-started/

  •  Tags:  
  • Related