使用转换器和提供程序而不是属性映射时,如何使ModelMapper.validate()成功? [英] How to have ModelMapper.validate() succeed when using converters and providers instead of property mapping?

查看:109
本文介绍了使用转换器和提供程序而不是属性映射时,如何使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;
}

我需要双向映射,因此我应该能够映射实体-> DTO->实体.在此示例中,属性类型恰好是LocalDateTime,但可以是需要从String进行解析的任何类型(只是说,我一般没有更好的方法来映射LocalDateTime,而是一般而言).

I need birectional mapping so I should be able to map Entity -> DTO -> Entity. In this example the property type happens to be LocalDateTime but could be any type that needs parsing from String or so (just to say that I am not after better way to map LocalDateTime but in general).

映射没有问题.我创建了TypeMap,添加了Converter,并为LocalDateTime添加了Provider,因为它确实注意到具有公共默认构造函数. 此处.

There are no problems in mapping. I create TypeMap, add Converter and for LocalDateTime a Provider also since it does note have public default constructor. Something like here.

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

If I had in my DTO also LocalDateTime createdTime(or String createdTime in my Entity) then ModelMapper.validate() would be happy. But I do not have and I need to create all the converting stuff.

所有这些导致ModelMapper.validate()抱怨:

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

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

The code I currently use for validating mapping for LocalDateTime case is:

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();

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

(so I am not doing any actual mapping but validating the mapping)

使用

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方法允许指定提供程序,该提供程序用于在TypeMap中提供映射属性的实例.

The setPropertyProvider method allows to specify a Provider to be used for providing instances of mapped properties within a TypeMap.

所以当你写的时候:

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

这不适合这种情况,因为我们没有在String类型的属性到LocalDateTime类型的属性的映射中使用此提供程序.最好将其移至上方以与 DTO->实体 TypeMap关联(错误消息是对此的很好提示).因此应该如此.

It does not fit the case because we are not using this provider in the mapping of a property of the String type to a property of a LocalDateTime type. It should rather be moved above to be associated with the DTO -> Entity TypeMap (The error message is by the way a good hint about that). So it should rather be.

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

这很合理,因为我们正在使用提供程序来提供实例,以将DTO(String createdTime;)的String属性映射到实体(LocalDateTime createdTime;)的LocalDateTime属性.

Which makes perfect sense because we are using the provider to provide instance for the mapping of a String property of the DTO (String createdTime;) to a LocalDateTime property of the Entity (LocalDateTime createdTime;).

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

On the other hand the converter should be added to the ModelMapper before the corresponding provider.

也留在mm.createTypeMap(String.class, LocalDateTime.class)中,我的编译器抱怨说已经存在类似的类型映射,因此无需创建新的类型映射.因此,我可以将其丢弃.

Also leaving in mm.createTypeMap(String.class, LocalDateTime.class), my compiler complains that a similar typemap already exist and there is no need to create a new one. So with that I can discard it.

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

With these two changes, my bean looks like:

@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().这对我有用.请测试并在您身边查看.

Notice that I am calling validate() before returning the bean. This works for me. Please test and see on your side.

这篇关于使用转换器和提供程序而不是属性映射时,如何使ModelMapper.validate()成功?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆