前端如何使用Hibernate乐观锁版本属性?
Posted
技术标签:
【中文标题】前端如何使用Hibernate乐观锁版本属性?【英文标题】:How to use the Hibernate optimistic locking version property on the front end? 【发布时间】:2010-11-28 05:47:54 【问题描述】:使用实体的版本属性进行乐观锁定工作正常且易于实现:
<version property="VERSION" type="int" column="EX_VERSION" />
实体具有以下类型的属性:
private int VERSION;
public int getVERSION() return VERSION;
public void setVERSION(int VERSION) this.VERSION = VERSION;
到目前为止,一切都很好。现在,服务方法为上面的实体返回一个数据传输对象 (DTO),视图以 html 格式显示。对于更新页面,VERSION 属性存储在 HTML 隐藏字段中并与表单一起提交。
目的是使用版本属性来确保如果显示的信息带有旧版本,用户的更新将失败。
控制器通过调用包含更新信息(包括版本属性)的 DTO 的服务方法来响应用户更新请求,而服务方法又使用数据访问对象 (DAO) 来持久化更改:
public void update(SimpleDTO dto)
SimplyEntity entity = getSimpleDao().load(dto.getId());
copyProperties(dto, entity); // all properties, including VERSION copied to entity
getSimpleDao().update(entity);
问题是通过 copyProperties(...) 复制到实体中的版本属性不受 Hibernate 的尊重。我在以下论坛中找到了原因:https://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068
简而言之,当调用 load() 时,Hibernate 会将 version 属性缓存在会话缓存中,随后将其值更改为什么都没有关系。我同意这是正确的行为,但是 Bosses 指示我通过 HTML 表单属性传递版本(如果有更好的模式,我很乐意听到)。
我现在正在探索的一个解决方案是在更新发生之前使用 hibernateTemplate.evict(simpleEntity) 设置它的版本后从会话中逐出实体。我希望这可行,但似乎效率不高。
我想要求 Hibernate 检查实例本身的版本属性,而不仅仅是从会话缓存中检查。
提前感谢您的回答!
-- LES
【问题讨论】:
从会话中驱逐()实体有效。 :) 保持开放,看看是否有我有见地的答案...... 【参考方案1】:您真的需要使用 DTO 吗?如果您传递实际的实体,您就不会遇到这个问题 - 您也不必再次加载实体,这对性能来说并不是很好。
但是,即使您确实有使用 DTO 的正当理由,我也不太明白为什么您会在保存之前尝试更新 新重新加载 实体的版本号。考虑工作流程中可能出现的不同场景:
-
最初加载实体,版本 = V1
它已转移到 DTO,然后转到 UI,然后返回并准备保存。
实体再次加载,版本 = V2
你现在有两种可能:
-
V1 == V2。 Peachy,你什么都不用做。
V1 小于 V2,这意味着实体在您编辑时被其他人更新。没有理由尝试将版本设置为 V1 并尝试保存,因为保存将失败。您可以使用 V2 保存它(从而覆盖其他人的更改)或立即失败。(不涉及 Hibernate)。
【讨论】:
1.可能需要重新加载,因为 DTO 可能不完全包含所有实体字段,只是一个子集。 2. 正如评论(也可以在forum.hibernate.org/viewtopic.php?t=977889a 底部的链接处阅读),evict 可以在这里提供帮助。以上是关于前端如何使用Hibernate乐观锁版本属性?的主要内容,如果未能解决你的问题,请参考以下文章