Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ModelMapper: matches multiple source property hierarchies

I cannot resolve modelMapper error. Do you have any ideas where is the issue?

NB: In view java.sql.Time doesn't have non-argument constructor I didn't find the better way than to write converter

org.modelmapper.ConfigurationException: ModelMapper configuration errors:

1) The destination property 
biz.models.CarWash.setSecondShift()/java.util.Date.setTime() matches 
multiple source property hierarchies:

biz.dto.CarWashDTO.getFirstShift()/java.time.LocalTime.getSecond()
biz.dto.CarWashDTO.getSecondShift()/java.time.LocalTime.getSecond()

The error was made by this code

@SpringBootTest
@RunWith(SpringRunner.class)
public class CarWashDTO2CarWash {

@Autowired
protected ModelMapper modelMapper;

@Test
public void testCarWashDTO2CarWash_allFiledShouldBeConverted(){
    CarWashDTO dto = CarWashDTO.builder()
            .name("SomeName")
            .address("SomeAddress")
            .boxCount(2)
            .firstShift(LocalTime.of(9, 0))
            .secondShift(LocalTime.of(20, 0))
            .phoneNumber("5700876")
            .build();

    modelMapper.addConverter((Converter<CarWashDTO, CarWash>) mappingContext -> {
        CarWashDTO source = mappingContext.getSource();
        CarWash destination = mappingContext.getDestination();
        destination.setId(source.getId());
        destination.setFirstShift(source.getFirstShift() == null ? null : Time.valueOf(source.getFirstShift()));
        destination.setSecondShift(source.getSecondShift() == null ? null : Time.valueOf(source.getSecondShift()));
        destination.setEnable(true);
        destination.setAddress(source.getAddress());
        destination.setBoxCount(source.getBoxCount());
        destination.setName(source.getName());
        destination.setDateOfCreation(source.getDateOfCreation());
        return destination;
    });

    final CarWash entity = modelMapper.map(dto, CarWash.class);
    assertNotNull(entity);
    assertEquals(2, entity.getBoxCount().intValue());
    assertEquals("SomeAddress", entity.getAddress());
    assertEquals("SomeName", entity.getName());
}

}

The modelmapper bean is built by the next configuration

@Bean
public ModelMapper modelMapper(){
    return new ModelMapper();
}

Dto:

public class CarWashDTO {
private Long id;
private String name;
private String address;
private String phoneNumber;
private Integer boxCount;
private LocalTime firstShift;
private LocalTime secondShift;
private LocalDateTime dateOfCreation;
}

Entity (firstShift and secondShift have java.sql.Time type):

public class CarWash {
private Long id;
private String name;
private String address;
private String phoneNumber;
private Integer boxCount;
private Time firstShift;
private Time secondShift;
private LocalDateTime dateOfCreation;
private Boolean enable;
private Owner owner;
}
like image 422
Bizon4ik Avatar asked Apr 14 '18 13:04

Bizon4ik


People also ask

What is the use of ModelMapper?

Model Mapper The main role of ModelMapper is to map objects by determining how one object model is mapped to another called a Data Transformation Object (DTO).

How do you use a model mapper converter?

The first is by adding the converter to a ModelMapper: modelMapper. addConverter(personConverter); This, in turn, sets the converter against the TypeMap corresponding to the source and destination types Person and PersonDTO .

What is Model Mapper in spring boot?

ModelMapper Introduction To avoid having to write cumbersome/boilerplate code to map DTOs into entities and vice-versa, we are going to use a library called ModelMapper. The goal of ModelMapper is to make object mapping easy by automatically determining how one object model maps to another.

What is property mapping in modelmapper?

Property Mapping. For most object models, ModelMapper does a good job of intelligently mapping source and destination properties. But for certain models where property and class names are very dissimilar, a PropertyMap can be created to define explicit mappings between source and destination properties.

Which destination property matches multiple source property hierarchies?

The destination property com..BaseEntity.setId () matches multiple source property hierarchies......... The version of org.modelmapper that I am using is: 2.0.0

How do you map lists in modelmapper with generic types?

In this tutorial, we explained how lists are mapped by manipulating generic types in ModelMapper. We can make use of TypeToken, generic type mapping, and property mapping to create object list types and make complex mappings. The complete source code for this article is available over on GitHub.

How does modelmapper compare private fields in the mapping classes?

By doing so, ModelMapper can compare private fields in the mapping classes (objects). In this configuration, it's not strictly necessary that all fields with the same names exist in both classes. Several Matching Strategies are allowed.


3 Answers

try modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT)

like image 156
antongarakh Avatar answered Oct 21 '22 09:10

antongarakh


This resolved my problem: modelMapper.getConfiguration().setAmbiguityIgnored(true);

like image 25
Adauto Nobrega Avatar answered Oct 21 '22 10:10

Adauto Nobrega


You need to customize ModelMapper configuration during Bean initialization with the help of a PropertyMap: http://modelmapper.org/user-manual/property-mapping/

@Bean
public ModelMapper modelMapper(){
    ModelMapper mm = new ModelMapper();

    PropertyMap<CarWashDTO, CarWash> propertyMap = new PropertyMap<CarWashDTO, CarWash> (){
        protected void configure() {
            map(source.getId()).setId(null);
        }
    }

    mm.addMappings(propertyMap);
    return mm;
}
like image 4
socona Avatar answered Oct 21 '22 11:10

socona