ModelMapper handling java 8 Optional<MyObjectDto> fields to Optional<MyObject>

对着背影说爱祢 提交于 2019-12-24 05:10:16

问题


I've been using modelmapper and java 8 Optionals all around the application which was working fine because they were primitive types; until I changed one of my model objects' field to Optional type. Then all hell broke loose. Turns out many libraries cannot handle generics very well.

Here is the structure

public class MyObjectDto
{
   private Optional<MySubObjectDto> mySubObject;
}

public MyObject
{
   privae Optional<MySubjObject> mySubObject;
}

When I attempt to map MyObjectDto to MyObject, modelmapper calls

public void setMySubObject(Optional<MySubObject> mySubObject){
   this.mySubObject = mySubObject;
}

with Optional<MySubObjectDto>, which I don't understand how that's even possible (there is no inheritance between them). Of course that crashes fast. For now I've changed my setters to accept Dto type just to survive the day but that's not going to work on the long run. Is there a better way to get around this, or shall I create an issue?


回答1:


So I digged into the modelmapper code and have done this looking at some generic implementations:

modelMapper.createTypeMap(Optional.class, Optional.class).setConverter(new OptionalConverter());

public class OptionalConverter implements ConditionalConverter<Optional, Optional> {

  public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
    if (Optional.class.isAssignableFrom(destinationType)) {
      return MatchResult.FULL;
    } else {
      return MatchResult.NONE;
    }
  }

  private Class<?> getElementType(MappingContext<Optional, Optional> context) {
    Mapping mapping = context.getMapping();
    if (mapping instanceof PropertyMapping) {
      PropertyInfo destInfo = ((PropertyMapping) mapping).getLastDestinationProperty();
      Class<?> elementType = TypeResolver.resolveArgument(destInfo.getGenericType(),
                                                          destInfo.getInitialType());
      return elementType == TypeResolver.Unknown.class ? Object.class : elementType;
    } else if (context.getGenericDestinationType() instanceof ParameterizedType) {
      return Types.rawTypeFor(((ParameterizedType) context.getGenericDestinationType()).getActualTypeArguments()[0]);
    }

    return Object.class;
  }

  public Optional<?> convert(MappingContext<Optional, Optional> context) {
    Class<?> optionalType = getElementType(context);
    Optional source = context.getSource();
    Object dest = null;
    if (source != null && source.isPresent()) {
      MappingContext<?, ?> optionalContext = context.create(source.get(), optionalType);
      dest = context.getMappingEngine().map(optionalContext);
    }

    return Optional.ofNullable(dest);
  }

}


来源:https://stackoverflow.com/questions/28603853/modelmapper-handling-java-8-optionalmyobjectdto-fields-to-optionalmyobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!