java - 使用转换器和提供者而不是属性映射时如何让 ModelMapper.validate() 成功?
问题描述
有类似的东西:
@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
而是在一般情况下)。
映射没有问题。我 create TypeMap
、 addConverter
和 for LocalDateTime
aProvider
也是因为它确实有公共默认构造函数。像这里的东西。
如果我的 DTO 也有LocalDateTime createdTime
(或String createdTime
我的Entity
),那么我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;
) 的 String 属性映射到 Entity () 的 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() 。这对我有用。请测试并在您身边查看。
推荐阅读
- python - 为什么求和和积分会给出不同的结果?
- php - errno: 150 "Foreign key constraint is incorrectly formed" in Laravel migration
- python - Applying methods to multiple datasets in pandas
- scala - DropDuplicates 没有给出预期的结果
- snmp - 编辑 MIB 模块
- javascript - 模态窗口内容显示在主窗口中
- php - PHP Select From Postgres Unexpected Character
- python - stop while loop when the text ends
- c++ - C++ 可以使用移动语义将数据从一个向量移动到另一个向量
- coverity - 如何在 Coverity Scan 中设置组件