我希望我的可审核(@CreatedDate
和 @LastModifiedDate
)MongoDB 文档与 ZonedDateTime
字段一起使用。
显然 Spring Data 不支持这种类型(查看 org.springframework.data.auditing.AnnotationAuditingMetadata
)。
框架版本:Spring Boot 2.0.0和Spring Data MongoDB 2.0.0
Spring Data审计错误:
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 MongoConfiguration {
}
可审计实体:
public abstract class BaseDocument {
@CreatedDate
private ZonedDateTime createdDate;
@LastModifiedDate
private ZonedDateTime lastModifiedDate;
}
我尝试过的事情
我还尝试为 ZonedDateTime
创建自定义转换器,但 Spring Data 不考虑它。 DateConvertingAuditableBeanWrapper
类有一个 ConversionService
,它在构造方法中使用 JodaTimeConverters
、Jsr310Converters
和 ThreeTenBackPortConverters 配置
。
自定义转换器:
@Component
public class LocalDateTimeToZonedDateTimeConverter implements Converter<LocalDateTime, ZonedDateTime> {
@Override
public ZonedDateTime convert(LocalDateTime source) {
return source.atZone(ZoneId.systemDefault());
}
}
Spring Data DateConvertingAuditableBeanWrapper:
class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory {
abstract static class DateConvertingAuditableBeanWrapper implements AuditableBeanWrapper {
private final ConversionService conversionService;
}
}
是否可以审核 ZonedDateTime
字段?
如何注册转换器?
最佳答案
创建一个 DateTimeProvider
提供审计时使用的当前时间:
@Component("dateTimeProvider")
public class CustomDateTimeProvider implements DateTimeProvider {
@Override
public Optional<TemporalAccessor> getNow() {
return Optional.of(ZonedDateTime.now());
}
}
然后:
- 引用
DateTimeProvider
@EnableMongoAuditing
中的组件注释; - 创建
Converter
sDate
和ZonedDateTime
; - 添加
Converter
实例到MongoCustomConversions
实例; - 公开
MongoCustomConversions
实例为@Bean
.
@Configuration
@EnableMongoAuditing(dateTimeProviderRef = "dateTimeProvider")
public class MongoConfiguration {
@Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new DateToZonedDateTimeConverter());
converters.add(new ZonedDateTimeToDateConverter());
return new MongoCustomConversions(converters);
}
class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
@Override
public ZonedDateTime convert(Date source) {
return source == null ? null :
ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
@Override
public Date convert(ZonedDateTime source) {
return source == null ? null : Date.from(source.toInstant());
}
}
}
但是,我不会使用 ZonedDateTime
以此目的。我会坚持 OffsetDateTime
:
OffsetDateTime
,ZonedDateTime
andInstant
all store an instant on the time-line to nanosecond precision. Instant is the simplest, simply representing the instant.OffsetDateTime
adds to the instant the offset from UTC/Greenwich, which allows the local date-time to be obtained.ZonedDateTime
adds full time-zone rules.It is intended that
ZonedDateTime
orInstant
is used to model data in simpler applications. This class may be used when modeling date-time concepts in more detail, or when communicating to a database or in a network protocol.
关于java - 在 Spring Data MongoDB 中为 ZonedDateTime 注册一个新的 Date Converter Auditable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43236431/