ModelMapper с несколькими конвертерами и провайдерами
У меня есть два провайдера, и ModelMapper использует один для неправильного свойства! В моем случае у меня есть UserProvider и UfProvider, он вызывает UserProvider для экземпляра UfUi, и я получил эту ошибку:
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:
Вот мой картограф:
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;
}
}
Проверка исходного кода ModelMapper, кажется, что я могу использовать только один конвертер, поставщик для каждого Mapper, что объясняет, почему он использует неправильный поставщик для создания экземпляра другого типа. Даже если я использую провайдера и конвертер по свойству, он не работает, так как больше конверторов я добавляю к своим свойствам, я просто заменяю тот же самый в самом картографе!
И, посмотрев еще дальше на ModelMapper, я понял, что MappingContext свойства Uf имеет неправильного провайдера ( UserProvider), если у каждого свойства есть собственный контекст, это не может произойти.