gpt4 book ai didi

java - Spring 数据 JPA : Delete Optimistic Locking semantics

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:39:45 24 4
gpt4 key购买 nike

有一个实体 Foo 带有 @Version 列。如果我想删除它,我希望 Spring Data JPA 和/或 Hibernate 检查 @Version 列的当前值是否与数据库中的值匹配。如果不是,删除应该被拒绝。这与分离实体的预期一样有效:

@Transactional
public void delete(Foo foo) {
fooRepository.delete(foo); // throws ObjectOptimisticLockingFailureException
}

但是,如果我先从存储库加载实体,然后使用不同版本在同一事务中删除它,则无论 @Version 列的值如何,删除都会通过:

@Transactional
public void delete(int fooId, long version) {
Foo foo = fooRepository.findOne(fooId);
foo.setVersion(version);
fooRepository.delete(foo); // passes regardless of value of version
}

当我查看 Hibernate 调试输出时,执行了版本比较(delete from foo where id=? and version=?)但没有达到我预期的效果。

我错过了什么?

最佳答案

来自JPA specification , 3.4.2 部分:

An entity may access the state of its version field or property or export a method for use by the application to access the version, but must not modify the version value. With the exception noted in section 4.10, only the persistence provider is permitted to set or update the value of the version attribute in the object.

version 属性的目的是防止我们在当前持久化上下文中加载对象后可能发生的并发更新,Hibernate 通过忽略您手动设置的任何值来实现它,而是使用从加载对象时的数据库。为了验证这一点,enable还打印绑定(bind)变量值,您会注意到使用了数据库中的值。

例如,在使用 DTO 时实际使用的标准解决方案是在从 DTO 更新实体状态时手动执行检查:

if (entity.getVersion() != dto.getVersion()) {
throw new OptimisticLockException("...");
}

当然,您可以通过扩展一个基类来使它更通用,该基类为所有版本可用的实体提供此检查,或者在某些 util 方法中。比如有的作者直接在version setter中做:

public void setVersion(long version) {
if (this.version != version) {
throw new OptimisticLockException("...");
}
}

Hibernate 会自动为分离的实体执行此检查,如 DefaultMergeEventListener 的实现中所示。 :

else if (isVersionChanged(entity, source, persister, target)) {
if (source.getFactory().getStatistics().isStatisticsEnabled()) {
source.getFactory().getStatisticsImplementor()
.optimisticFailure(entityName);
}
throw new StaleObjectStateException(entityName, id);
}

关于java - Spring 数据 JPA : Delete Optimistic Locking semantics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43779279/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com