20

I learn how to use ModelMapper by official documentation http://modelmapper.org/getting-started/

There is code sample for explicit mapping using java 8

modelMapper.addMappings(mapper -> {
  mapper.map(src -> src.getBillingAddress().getStreet(),
      Destination::setBillingStreet);
  mapper.map(src -> src.getBillingAddress().getCity(),
      Destination::setBillingCity);
});

How to use this code correctly? When I type this code snippet in IDE, IDE show me message cannot resolve method map

enter image description here

Bentaye
  • 9,403
  • 5
  • 32
  • 45
hudrogen
  • 342
  • 1
  • 3
  • 13

2 Answers2

58

They missed a step in this example, the addMappings method they use is the addMappings from TypeMap, not from ModelMapper. You need to define a TypeMap for your 2 objects. This way:

// Create your mapper
ModelMapper modelMapper = new ModelMapper();

// Create a TypeMap for your mapping
TypeMap<Order, OrderDTO> typeMap = 
    modelMapper.createTypeMap(Order.class, OrderDTO.class);

// Define the mappings on the type map
typeMap.addMappings(mapper -> {
    mapper.map(src -> src.getBillingAddress().getStreet(), 
                      OrderDTO::setBillingStreet);
    mapper.map(src -> src.getBillingAddress().getCity(), 
                      OrderDTO::setBillingCity);
});

An other way would be to use the addMappings method from ModelMapper. It does not use lambdas and takes a PropertyMap. It is short enough too:

ModelMapper modelMapper = new ModelMapper();
modelMapper.addMappings(new PropertyMap<Order, OrderDTO>() {
  @Override
  protected void configure() {
    map().setBillingStreet(source.getBillingAddress().getStreet());
    map().setBillingCity(source.getBillingAddress().getCity());
  }
});
Bentaye
  • 9,403
  • 5
  • 32
  • 45
  • 13
    I wish the authors of java libraries would be explicit with their examples. I was digging around this page for three days trying to find out how to do this. – Josh J Jan 17 '19 at 16:50
  • 2
    Any ideas why the first approach throws error but the second works...? that's my case by the way – Manuel Gonçalves Mar 26 '20 at 21:45
  • @ManuelGonçalves What error do you get? Compilation error, or runtime error? And what is it? – Bentaye Mar 27 '20 at 12:47
3

if the source and destination type are different. For example,

@Entity
class Student {
    private Long id;
    
    @OneToOne
    @JoinColumn(name = "laptop_id")
    private Laptop laptop;
}

And Dto ->

class StudentDto {
    private Long id;
    private LaptopDto laptopDto;
}

Here, the source and destination types are different. So, if your MatchingStrategies are STRICT, you won't able to map between these two different types. Now to solve this, Just simply put this below code in the constructor of your controller class or any class where you want to use ModelMapper->

private ModelMapper modelMapper;

public StudentController(ModelMapper modelMapper) {
    this.modelMapper = modelMapper;
    this.modelMapper.typeMap(Student.class, StudentDto.class).addMapping(Student::getLaptop, StudentDto::setLaptopDto);
}
        

That's it. Now you can use ModelMapper.map(source, destination) easily. It will map automatically

modelMapper.map(student, studentDto);
Muhammad Saimon
  • 233
  • 2
  • 10
  • I stumbled upon this answer. I was myself looking for a solution which happens to be for similar kind of issue but not exactly same. I'm looking for solution to https://stackoverflow.com/questions/64604829/using-modelmapper-on-different-data-types-with-same-attribute-name What could be possible solution for this? – Nitish Prajapati Oct 30 '20 at 09:01