如何使用 ModelMapper 处理 Set 到 List 的转换

How to handle conversion of a Set to a List with ModelMapper

我有以下 类:

public class MyEntity {
  private Set<MyOtherEntity> other;
}

public class MyDTO {
  private List<MyOtherDTO> other;
}

我创建了两个 PropertyMaps(使用 ModelMapper),每次从 DTO 转换一个

public class DTOToEntityPropertyMap extends PropertyMap<MyDTO, MyEntity> {
  @Override
  protected void configure() {
    List<MyOtherDTO> myOtherDTOs = source.getOther();
    Set<MyOtherEntity> myOtherEntities = new HashSet<>();
    for (MyOtherDTO myOtherDTO : myOtherDTOs) {
      MyOtherEntity myOtherEntity = ModelMapperConverterService.convert(myOtherDTO, MyOtherEntity.class);
      myOtherEntities.add(myOtherEntity);
    }
    map().setOther(myOtherEntities);
  }
}

public class EntityToDTOPropertyMap extends PropertyMap<MyEntity, MyDTO> {
  @Override
  protected void configure() {
    Set<MyOtherEntity> myOtherEntities = source.getOther();
    List<MyOtherDTO> myOtherDTOs = new ArrayList<>();
    for (MyOtherEntity myOtherEntity : myOtherEntities) {
      MyOtherDTO myOtherDTO = ModelMapperConverterService.convert(myOtherEntity, MyOtherDTO.class);
      myOtherDTOs.add(myOtherDTO);
    }
    map().setOther(myOtherDTOs);
  }
}

PropertyMaps 添加到 ModelMapper 会产生以下错误:

Caused by: org.modelmapper.ConfigurationException: ModelMapper configuration errors:

1) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.

我想我不能在 PropertyMap 的配置中使用 List.add()

那么,在ModelMapper中实现List到Set和反向转换的最佳方式是什么?

PropertyMap 必须使用它来映射属性。如果你放入不同逻辑的东西,它会抛出异常。

所以,你有下一个选项(我把例子放在一个方向,另一个是一样的):

选项 1:确保 PropertyMap 匹配属性

使用 属性 映射并确保 ModelMapper 将使用它,查看 Matching Strategies:

的规则
  • Standard: by default.
  • Loose
  • Strict

使用确保您的 属性 列表 other 与目的地 属性 other 匹配的列表。例如,如果您使用 Strict Strategy 并且顺序不正确,它将不会匹配它。

然后,如果您确定 属性 将匹配 ModelMapper 将按照其规则为您映射 属性,或者如果您需要它,您将能够创建一个 PropertyMap 使用源 MyOtherEntity 和目标 MyOtherDTO 并将其添加到您的 ModelMapper 实例。

public class DTOToEntityPropertyMap extends PropertyMap<MyOtherEntity, MyOtherDTO> {
  @Override
  protected void configure() {
    map().setPropertyOfOther(source.getPropertyOfOther());
    //and so on...
  }
}

modelMapper.addMappings(new DTOToEntityPropertyMap());

注意: 如果你的父映射(在你的例子中是 MyEntity 到 MyDto)有其他 PropertyMap 你需要添加列表的 PropertyMapping 类 在父级之前,如果不是它不会使用此 属性 映射。

选项 2:创建列表转换器并使用它

其他选项是创建列表 类 的转换器 (MyOtherEntity -> MyOtherDto) 并在父 PropertyMap 中使用它。

Converter<Set<MyOtherEntity> , List<MyOtherDto>> toOtherDto = new Converter<Set<MyOtherEntity> , List<MyOtherDto>>() {
  public String convert(MappingContext<Set<MyOtherEntity> , List<MyOtherDto>> context) {
    Set<MyOtherEntity> source = context.getSource();
    List<MyOtherDto> destination = context.getDestination();
    //Convert it using the logic you want (by hand for example)

    return destination;
  }
};

那么您必须在您的父级 PropertyMap 中使用它,如下所示:

public class EntityToDTOPropertyMap extends PropertyMap<MyEntity, MyDTO> {

  Converter<Set<MyOtherEntity> , List<MyOtherDto>> toOtherDto = new Converter<Set<MyOtherEntity> , List<MyOtherDto>>() {
    public String convert(MappingContext<Set<MyOtherEntity> , List<MyOtherDto>> context) {
      Set<MyOtherEntity> source = context.getSource();
      List<MyOtherDto> destination = context.getDestination();
      //Convert it using the logic you want (by hand for example)

      return destination;
    }
  };

  @Override
  protected void configure() {
    using(toOtherDto).map(source.getOther()).setOther(null);
  }
}

然后确保将此 PropertyMap 添加到您的 ModelMapper 实例中:

modelMapper.addMappings(new EntityToDTOPropertyMap());