在 Spring Boot 项目中,我使用 @CreatedDate 之类的注释来保存有关创建/更新相应文档的日期信息。整个项目都使用 ZonedDateTime,因此带注释的字段也是 ZonedDateTime。为了启用 Mongo 的日期格式和 ZonedDateTime 之间的转换,使用了自定义转换器。
现在,当使用 Spring Boot 1.5.x 时,自定义转换器可以完美地用于可审计字段。在 Spring Boot 2.0.x 中,自定义转换器适用于所有字段,但不适用于可审计的字段。因此,如果我删除@EnableMongoAuditing,一切正常(整个项目中的所有 ZonedDateTime 字段都保存到 Mongo 并正确读取),但创建/更新的日期字段为空。如果我启用 mongo 审计,我在尝试保存文档时会遇到以下异常:
java.lang.IllegalArgumentException: Invalid date type for member <MEMBER NAME>!
Supported types are [org.joda.time.DateTime, org.joda.time.LocalDateTime, java.util.Date, java.lang.Long, long]
我的 Mongo 配置:
@Configuration
@EnableMongoAuditing
public class MongoConfig {
@Bean
public MongoCustomConversions customConversions(){
List<Converter<?,?>> converters = new ArrayList<>();
converters.add(new ZonedDateTimeToDateConverter());
converters.add(new DateToZonedDateTimeConverter());
return new MongoCustomConversions(converters);
}
}
这是相应字段的样子:
abstract class BaseModel {
@Id
private String id;
@CreatedDate
private ZonedDateTime created;
@LastModifiedDate
private ZonedDateTime updated;
}
除了降级到 Spring Boot 1.5.x 之外,是否有办法让转换器适用于 mongo 可审计字段?
最佳答案
长话短说:
除了注册一个 MongoCustomConversions
bean。创建一个 DateTimeProvider
的 bean,并将其注册到您的 @EnableXXXAuditing(dateTimeProviderRef = "dateTimeProvider")
public class CustomDateTimeProvider implements DateTimeProvider {
@Override
public Optional<TemporalAccessor> getNow() {
return Optional.of(ZonedDateTime.now());
}
}
@Configuration
@EnableMongoAuditing(dateTimeProviderRef = "dateTimeProvider") // beanName
public class MongoConfig {
@Bean
public MongoCustomConversions customConversions(){
List<Converter<?,?>> converters = new ArrayList<>();
converters.add(new ZonedDateTimeToDateConverter());
converters.add(new DateToZonedDateTimeConverter());
return new MongoCustomConversions(converters);
}
// The DateTimeProvider bean with beanName="dateTimeProvider" is registered here
@Bean
public DateTimeProvider dateTimeProvider() {
return new CustomDateTimeProvider();
}
}
仅供引用:
当你使用@EnableXXXAuditing
时,Spring会注册一个AuditHandler。负责将审计数据添加到您的模型。它有两个主要组成部分:DateTimeProvider和 AuditorAware<?> .您可以在 AuditHandler
中注册这两个组件,方法是在 @EnableXXXAuditing
中声明它们。例如:
@EnableXXXAuditing(
auditorAwareRef = "auditorAware", // beanName
dateTimeProviderRef = "dateTimeProvider" // beanName
)
- DateTimeProvider简而言之,负责
@CreatedDate
和@LastModifiedDate
- AuditorAware简而言之,负责
@CreatedBy
和@LastModifiedBy
DateTimeProvider
的默认实现是返回 LocalDateTime
实例的 CurrentDateTimeProvider。这就是您的 ZonedDateTime
CreatedDate、LastModifiedDate 出现错误的原因。
关于java - Mongo 可审核的 ZonedDateTime 字段在 Spring Boot 2 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49878532/