java - 使用转换器和提供程序而不是属性映射时如何让 ModelMapper.validate() 成功?

标签 java mapping dto converters modelmapper

有类似的东西:

@Getter @Setter
public static class Entity {
    private int hash;
    private LocalDateTime createdTime;
}

@Getter @Setter
public static class DTO {
    private String hash;
    private String createdTime;
}

我需要双向映射,所以我应该能够映射 Entity -> DTO -> Entity。在这个例子中,属性类型恰好是 LocalDateTime 但可以是任何需要从 String 解析的类型(只是说我不是在寻找更好的方法来映射 LocalDateTime 但通常情况下)。

映射没有问题。我创建了 TypeMap,添加了 Converter 并为 LocalDateTime 添加了一个 Provider,因为它确实具有公共(public)默认构造函数。类似于 here .

如果我的 DTO 中还有 LocalDateTime createdTime(或 Entity 中的 String createdTime),那么 ModelMapper.validate() 会很高兴。但我没有,我需要创建所有转换的东西。

所有这些导致 ModelMapper.validate() 提示:

Unmapped destination properties found in TypeMap[DTO -> Entity]:  
    org.example.test.modelmapper.validation.TestIt$Entity.setCreatedTime()

我目前用于验证 LocalDateTime 情况的映射的代码是:

ModelMapper mm = new ModelMapper();
mm.createTypeMap(Entity.class, DTO.class);
mm.createTypeMap(DTO.class, Entity.class);
mm.createTypeMap(String.class, LocalDateTime.class)
        .setPropertyProvider(localDateTimeProvider);
mm.addConverter(toStringDate);
mm.validate();

(所以我没有做任何实际的映射,而是验证映射)

Provider<LocalDateTime> localDateTimeProvider =
        new AbstractProvider<LocalDateTime>() {
    @Override
    public LocalDateTime get() {
        return LocalDateTime.now();
    }
};

Converter<String, LocalDateTime> toStringDate = new AbstractConverter<>() {
    @Override
    protected LocalDateTime convert(String source) {
        return LocalDateTime.parse(source);
    }
};

询问更多细节/代码。我会根据需要更新问题

最佳答案

setPropertyProvider 方法允许指定一个 Provider,用于在 TypeMap 中提供映射属性的实例。

所以当你写的时候:

mm.createTypeMap(String.class, LocalDateTime.class)
        .setPropertyProvider(localDateTimeProvider);

它不适合这种情况,因为我们没有在将 String 类型的属性映射到 LocalDateTime 类型的属性时使用此提供程序。它应该移到上方以与 DTO -> Entity TypeMap 相关联(顺便说一句,错误消息是一个很好的提示)。应该如此。

mm.createTypeMap(DTO.class, Entity.class)
                .setPropertyProvider(localDateTimeProvider);

这非常有意义,因为我们使用提供程序来提供实例,用于将 DTO 的字符串属性 (String createdTime;) 映射到实体的 LocalDateTime 属性 (LocalDateTime createdTime;).

另一方面,转换器应该在相应的提供者之前添加到 ModelMapper。

还留在 mm.createTypeMap(String.class, LocalDateTime.class) 中,我的编译器提示说类似的类型映射已经存在,无需创建新类型映射。所以我可以丢弃它。

通过这两个更改,我的 bean 看起来像:

@Bean
ModelMapper demoModelMapper() {

   Provider<LocalDateTime> localDateTimeProvider =
   new AbstractProvider<LocalDateTime>() {
      @Override
      public LocalDateTime get() {
         return LocalDateTime.now();
      }
   };

   Converter<String, LocalDateTime> toStringDate = new AbstractConverter<String, 
   LocalDateTime>() {
      @Override
      protected LocalDateTime convert(String source) {
         return LocalDateTime.parse(source);
      }
   };

   ModelMapper mm = new ModelMapper();


   mm.createTypeMap(Entity.class, DTO.class);
   mm.addConverter(toStringDate);
   mm.createTypeMap(DTO.class, Entity.class)
     .setPropertyProvider(localDateTimeProvider);
   mm.validate();

   return mm;
}

请注意,我在返回 bean 之前调用了 validate()。这对我有用。请测试并查看您的身边。

关于java - 使用转换器和提供程序而不是属性映射时如何让 ModelMapper.validate() 成功?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59568360/

相关文章:

java - 在android中单击按钮后如何锁定微调器

java - 如何从 Java 中的 while 循环返回 count 的值

c# - Service Stack 的 DTO 模式真的有用吗?

c# - AutoMapper 的多态性

java - jsf ajax 必须是同样的形式吗?

java - 同时使用 java.endorsed.dirs 和 java.library.path 时发生冲突

entity-framework - 如何从 Entity Framework 中的元模型中获取多对多关系的实体到表映射

list - scala:将 List[ Tuple3[A,B,C] ] 转换为 Foo(A, B, List[C]) 的最短方法

java - 有没有比 if 序列更好的方法来处理事件?

java - Spring/Java项目层次结构: Where to put none model POJO classes?