带有 java.util.Date 字段的 MongoDB 文档的 Spring 乐观锁

Posted

技术标签:

【中文标题】带有 java.util.Date 字段的 MongoDB 文档的 Spring 乐观锁【英文标题】:Spring optimistic lock for MongoDB document with java.util.Date field 【发布时间】:2019-03-07 07:53:41 【问题描述】:

我正在尝试对现有 MongoDB 数据库中的文档实施乐观锁定。目前没有version 字段,我想避免添加它,因为我们将不得不停止应用程序。

但是有一个lastModified 日期字段,我似乎可以这样使用它:

@LastModifiedDate
@Version
private Date lastModified;

但是当我将此字段标记为@Version 并尝试保存项目时,出现以下异常:

找不到能够从 [java.lang.Date] 类型转换为 [java.lang.Number] 类型的转换器

所以,我还在我的配置中添加了 Date to Number 和 Long to Date 转换器:

@Configuration
public class MongoConfig extends AbstractMongoConfiguration 

    ...

    @Override
    public CustomConversions customConversions() 
        return new CustomConversions(CustomConversions.StoreConversions.NONE,
            Arrays.asList(
                new DateToNumberConverter(),
                new LongToDateConverter()
        ));
    

这就像对现有文档的魅力。但是当我尝试添加一个新文档时,我得到:

没有找到能够从 [java.lang.Integer] 类型转换为 [java.util.Date] 类型的转换器

如果我随后添加一个整数到日期转换器,那么新文档将保存在数据库中,但所有日期现在都是NumberLong 而不是ISODate,即是"lastModified" : ISODate("2018-10-02T07:30:12.005Z"),现在是"lastModified" : NumberLong("1538465479364")。这破坏了现有文档和新文档之间的一致性。

所以问题是:

    是否有可能将java.util.Date@Version 一起使用,以便在MongoDB 中将所有日期存储为ISODate? 除此之外,任何人都可以指出有关 Spring Data for MongoDB 中乐观锁定的文档:https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.optimistic-locking 吗?

【问题讨论】:

【参考方案1】:

目前似乎不可能使用 Date 作为版本字段,因为它在 MongoTemplate 中被强制转换为 Number。 我通过使用扩展 Spring Data MongoTemplate 并覆盖所需方法的自定义 MongoTemplate 解决了这个问题。不幸的是,我不得不复制粘贴很多代码,因为覆盖的逻辑在私有方法中。

【讨论】:

以上是关于带有 java.util.Date 字段的 MongoDB 文档的 Spring 乐观锁的主要内容,如果未能解决你的问题,请参考以下文章

在java.util.Date或java.sql.Date之间进行选择

在 java.util.Date 或 java.sql.Date 之间进行选择

util.date和sql.date的衔接处理

java.sql.Date和java.util.Date的区别

java.util.Date和java.util.Calendar及相关类

当我通过 JSON 获取输入时,如何在 Ibatis 中将 java.util.Date 映射到 MySql Date