java - Mongo 可审核的 ZonedDateTime 字段在 Spring Boot 2 中不起作用

标签 java spring mongodb spring-boot spring-data-mongodb

在 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。负责将审计数据添加到您的模型。它有两个主要组成部分:DateTimeProviderAuditorAware<?> .您可以在 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/

相关文章:

java - 使用 Spring 配置文件 (XML) 为除一个配置文件之外的所有配置文件声明 bean

java - Spark异常: Task not serializable (Even after class implements Serializable)

java - 格式标志转换不匹配异常

java - header 签名无效 - 使用 Apache POI 打开 XLS

java - 使用 ExpandableListView 时将菜单栏放在屏幕底部

javascript - 根据用户输入生成文件后下载文件

java - 如何在没有环境的情况下读取 application.properties 文件

MongoDB - 自动维护数据完整性

mongodb - 无法映射文件内存-mongo 需要 64 位构建更大的数据集

mongodb - 如何在 NoSQL 世界中实现数据库抽象/独立