0

I have two providers and ModelMapper is using the one to the wrong property! In my case I have UserProvider and UfProvider, it is calling UserProvider to a instance of UfUi and I got this error:

    Failed to set value 'UserModel [dtNasc=null, idUf=null, login=null, name=null, password=null, urlAvatar=null, cidade=null, posts=[], postScores=[], privatePostScores=[], privatePosts=[], privateTopicUsers=[], testDrives=[], testDriveScores=[], userRoles=[], logins=[], topicUserVieweds=[]]' on br.com.xlib.putariaBR.model.CidadeModel.setUf()

1 error
at org.modelmapper.internal.Errors.toMappingException(Errors.java:258)
at org.modelmapper.internal.PropertyInfoImpl$MethodMutator.setValue(PropertyInfoImpl.java:127)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:256)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:186)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:135)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:92)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:60)
... 43 more
Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@2220c5f7
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.modelmapper.internal.PropertyInfoImpl$MethodMutator.setValue(PropertyInfoImpl.java:125)
... 48 more
2018-05-10 20:56:53.150 [ERROR] br.com.xlib.putariaBR.service.impl.AbstractServiceImpl : org.modelmapper.MappingException: ModelMapper mapping errors:

Here is my mapper:

public class UiModelMapper {
    private static final Logger LOGGER = LogManager
            .getLogger(UiModelMapper.class);

        protected ModelMapper createMappings() {
        ModelMapper modelMapper;

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

            return modelMapper;
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

      public void mapCidade(CidadeModel cidadeModel, CidadeUi cidadeUi) {
        LOGGER.info("BEGIN");
        ModelMapper modelMapper = createMappings();
        modelMapper.addMappings(new CidadePropertyMap());

        LOGGER.info("Converting to cidadeUi:");
        modelMapper.validate();
        modelMapper.map(cidadeModel, cidadeUi);
        LOGGER.info("END");
    }
}

public class CidadePropertyMap
        extends AbstractPropertyMap<CidadeEntity, CidadeUi> {

    private static final Logger LOGGER = LogManager
            .getLogger(CidadePropertyMap.class);

    @Override
    protected void configure() {
        LOGGER.info("BEGIN");
        UserProvider userProvider = new UserProvider();

        with(userProvider).map().setUserAltered(source.getUserAltered());
        with(userProvider).map().setUserCreated(source.getUserCreated());

        UfProvider ufProvider = new UfProvider();
        UserListConverter userListConverter = new UserListConverter();

        with(ufProvider).map().setUf(source.getUf());

        using(userListConverter).map().setUsers(source.getUsers());
        LOGGER.info("END");
    }

}

public class UserProvider extends AbstractProvider<UserUi> {

    @Override
    protected UserUi get() {
        return new UserUi();
    }

}

public class UfProvider extends AbstractProvider<UfUi> {

    @Override
    protected UfUi get() {
        return new UfUi();
    }

}

public class UserListConverter
        extends AbstractConverter<List<UserModel>, List<UserModel>> {
    private static final Logger LOGGER = LogManager
            .getLogger(UserListConverter.class);

    @Override
    protected List<UserModel> convert(List<UserModel> userModels) {
        LOGGER.info("BEGIN");
        List<UserModel> userUis = new ArrayList<UserModel>();
        UiModelMapper uiModelMapper = new UiModelMapper();
        UserUi userUi;

        for (UserModel userModel : userModels) {
            userUi = new UserUi();
            uiModelMapper.mapUser(userModel, userUi);

            userUis.add(userUi);
        }

        LOGGER.info("END");
        return userUis;
    }

}

Checking the source code of ModelMapper, seems that I can only use one converter, provider per Mapper, that explains why it is using the wrong Provider to create a instance of a different type. Even if I use provider and converter by property it doesn't work, as more converter I add to my properties I just replace the same one inside the mapper itself!

And looking even further at ModelMapper, i realized that MappingContext of Uf property is with wrong provider ( UserProvider ), if each property has its own context it could not happen.

LottaLava
  • 889
  • 1
  • 9
  • 21

0 Answers0