Search code examples
spring-bootmappingmodelmapper

ModelMapper - A mapping already exists - Two configurations


I have two classes that use ModelMapper to convert entity to DTO. In each class I have a configuration in class's constructor to ModelMapper, to avoid convert all the relations into DTO and get StackOverflowError.

CompanyServiceImpl

private ModelMapper modelMapper;

@Autowired
public CompanyServiceImpl(ModelMapper modelMapper) {
    this.modelMapper = modelMapper;

    modelMapper.addMappings(skipCompanyServiceFieldsMap);
    modelMapper.addMappings(skipCompanyServiceModuleFieldsMap);
}

PropertyMap<CompanyServiceModule, CompanyServiceModuleDTO> skipCompanyServiceModuleFieldsMap = new PropertyMap<CompanyServiceModule, CompanyServiceModuleDTO>() {
    @Override
    protected void configure() {
        // Tells ModelMapper to NOT populate back references
        skip(destination.getCompanyService());
        skip(destination.getServiceModule().getCompanyServiceModules());
        skip(destination.getServiceModule().getService());
        skip(destination.getServiceModule().getServiceModuleLanguages());
        skip(destination.getServiceModule().getServiceModuleMenus());
    }
};

CompanyProfileImpl

private ModelMapper modelMapper;

@Autowired
public CompanyProfileImpl(ModelMapper modelMapper) {
    this.modelMapper = modelMapper;

    modelMapper.addMappings(skipCompanyProfileFieldsMap);
    modelMapper.addMappings(skipCompanyProfileModuleFieldsMap);
    modelMapper.addMappings(skipCompanyProfileServiceModuleFieldsMap);
}

PropertyMap<CompanyServiceModule, CompanyServiceModuleDTO> skipCompanyProfileServiceModuleFieldsMap = new PropertyMap<CompanyServiceModule, CompanyServiceModuleDTO>() {
    @Override
    protected void configure() {
        // Tells ModelMapper to NOT populate back references
        skip(destination.getCompanyProfileModules());
        skip(destination.getServiceModule());
        skip(destination.getCompanyService());
    }
};

When I run the application I'm getting the error:

A mapping already exists for com.closeupinternational.authorization.dtos.CompanyServiceModuleDTO.setCompanyService().

How can I have two configuration for ModelMapper, each one specific to the implemented service? Since in one case makes sense to bring some relations and in the other not.


Solution

  • I changed the instantiation of the class into constructor and not leave Spring to instantiate and treat as Singleton.

    private ModelMapper modelMapper;
    
    public CompanyProfileImpl() {
        // Necessary to not get in conflict with others
        this.modelMapper = new ModelMapper();
    
        modelMapper.addMappings(skipCompanyProfileFieldsMap);
        modelMapper.addMappings(skipCompanyProfileModuleFieldsMap);
        modelMapper.addMappings(skipCompanyServiceModuleFieldsMap);
    }