@Version 列不能立即使用 spring 数据 jdbc
@Version column is not working out of the box with spring data jdbc
我的版本列是这样定义的
@org.springframework.data.annotation.Version
protected long version;
使用 Spring 数据 JDBC 它总是尝试插入。更新没有发生。当我调试时,我看到 PersistentEntityIsNewStrategy
正在使用,这是默认策略。它有 isNew()
方法来确定被持久化的实体的状态。我确实看到 version 和 id 用于此确定。
但我的问题是谁负责在每次保存后增加版本列,以便在第二次调用 .save()
时,isNew()
方法可以 return false。
我们是否应该触发 BeforeSaveEvent
并处理 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's] 使得 markAudited
调用 markUpdated
而不是 markCreated
,因为版本列已经递增。我试图让我的 Listener 成为 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;
}
}
目前,您必须手动增加版本并且没有乐观锁定,即版本仅用于检查实体是否是新的。
有空缺issue for support of optimistic locking and there is even a PR open for it。
因此,此功能很可能会在即将到来的 1.1 里程碑中提供。
我的版本列是这样定义的
@org.springframework.data.annotation.Version
protected long version;
使用 Spring 数据 JDBC 它总是尝试插入。更新没有发生。当我调试时,我看到 PersistentEntityIsNewStrategy
正在使用,这是默认策略。它有 isNew()
方法来确定被持久化的实体的状态。我确实看到 version 和 id 用于此确定。
但我的问题是谁负责在每次保存后增加版本列,以便在第二次调用 .save()
时,isNew()
方法可以 return false。
我们是否应该触发 BeforeSaveEvent
并处理 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's] 使得 markAudited
调用 markUpdated
而不是 markCreated
,因为版本列已经递增。我试图让我的 Listener 成为 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;
}
}
目前,您必须手动增加版本并且没有乐观锁定,即版本仅用于检查实体是否是新的。
有空缺issue for support of optimistic locking and there is even a PR open for it。 因此,此功能很可能会在即将到来的 1.1 里程碑中提供。