首页 文章

在Spring Data MongoDB for ZonedDateTime中注册一个可审计的新Date Converter

提问于
浏览
9

我希望我的可审计( @CreatedDate@LastModifiedDate )MongoDB文档与 ZonedDateTime 字段一起使用 .

显然,Spring Data不支持这种类型(请查看 org.springframework.data.auditing.AnnotationAuditingMetadata ) .

框架版本: Spring Boot 2.0.0Spring 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 ,它在构造函数方法中使用 JodaTimeConvertersJsr310ConvertersThreeTenBackPortConverters 进行配置 .

定制转换器:

@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 字段?

如何注册转换器?

1 回答

  • 1

    创建DateTimeProvider以提供审计时使用的当前时间:

    @Component("dateTimeProvider")
    public class CustomDateTimeProvider implements DateTimeProvider {
    
        @Override
        public Optional<TemporalAccessor> getNow() {
            return Optional.of(ZonedDateTime.now());
        }
    }
    

    然后:

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

相关问题