首页 > 解决方案 > @Version 列无法使用 spring 数据 jdbc 开箱即用

问题描述

我的版本列是这样定义的

@org.springframework.data.annotation.Version
protected long version;

使用 Spring Data JDBC,它总是试图插入。更新没有发生。当我调试时,我看到,PersistentEntityIsNewStrategy正在使用这是默认策略。它有isNew()方法来确定被持久化的实体的状态。我确实看到该版本和 id 用于此确定。

但我的问题是谁负责在每次保存后增加版本列,这样当第二次.save()调用时,该isNew()方法可以返回 false。

我们是否应该触发 aBeforeSaveEvent并处理 Version 列的增量?这足以应付OptimisticLock吗?

编辑 我添加了一个 ApplicationListener 来像这样收听 BeforeSaveEvent 。

public ApplicationListener<BeforeSaveEvent> incrementingVersion() {
    return event -> {
        Object entity = event.getEntity();
        if (BaseDataModel.class.isAssignableFrom(entity.getClass())) {
            BaseDataModel baseDataModel = (BaseDataModel) entity;
            Long version = baseDataModel.getVersion();
            if (version == null) {
                baseDataModel.setVersion(0L);
            } else {
                baseDataModel.setVersion(version + 1L);
            }
        }
    };
}

所以现在版本列有效,但其余可审核字段@CreatedAt, @CreatedBy,@LastModifiedDate and @LastModifiedBy未设置!

编辑2

创建了一个新的 ApplicationListener ,如下所示。在这种情况下,我的自定义侦听器和 Spring 的 RelationalAuditingListener 都被调用了。但它仍然不能解决问题。因为侦听器的顺序[自定义一个后跟 spring 的] 使得markAudited调用markUpdated而不是markCreated,因为版本列已经增加。我试图让我的听众LOWEST_PRECEDENCE仍然没有运气。

我的自定义监听器在这里

public class CustomRelationalAuditingEventListener
    implements ApplicationListener<BeforeSaveEvent>, Ordered {

@Override
public void onApplicationEvent(BeforeSaveEvent event) {

    Object entity = event.getEntity();
    // handler.markAudited(entity);

    if (BaseDataModel.class.isAssignableFrom(entity.getClass())) {
        BaseDataModel baseDataModel = (BaseDataModel) entity;

        if (baseDataModel.getVersion() == null) {
            baseDataModel.setVersion(0L);
        } else {
            baseDataModel.setVersion(baseDataModel.getVersion() + 1L);
        }
    }
}

@Override
public int getOrder() {
    return LOWEST_PRECEDENCE;
}

}

标签: spring-data-jdbc

解决方案


目前,您必须手动增加版本并且没有乐观锁定,即版本仅用于检查实体是否是新的。

有一个开放的问题支持乐观锁定,甚至还有一个 PR 开放。因此,此功能很可能会在即将到来的 1.1 里程碑中提供。


推荐阅读