java 前端如何使用Hibernate的乐观锁版本属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1423307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use the Hibernate optimistic locking version property on the front end?
提问by les2
Optimistic locking using the version attribute for an entity works fine and is easy to implement:
使用实体的 version 属性的乐观锁定工作正常并且易于实现:
<version property="VERSION" type="int" column="EX_VERSION" />
The entity has a property of the following type:
该实体具有以下类型的属性:
private int VERSION;
public int getVERSION() { return VERSION; }
public void setVERSION(int VERSION) { this.VERSION = VERSION; }
So far, so good. Now service methods return a data transfer object (DTO) for the entity above, which the views display in HTML. For update pages, the VERSION attribute is stored in an HTML hidden field and submitted with the form.
到现在为止还挺好。现在,服务方法为上面的实体返回一个数据传输对象 (DTO),视图以 HTML 格式显示该对象。对于更新页面,VERSION 属性存储在 HTML 隐藏字段中并随表单提交。
The intent is to use the version property to ensure that a user's update will fail if the information displayed is accompanied by an old version.
目的是使用 version 属性来确保如果显示的信息伴随着旧版本,则用户的更新将失败。
The controller responds to a users update request by invoking a service method with the DTO containing the updated information (including the version property), and the service method in turn uses a data access object (DAO) to persist the changes:
控制器通过使用包含更新信息(包括版本属性)的 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);
}
The problem is that the version property copied into the entity by copyProperties(...) is not respected by Hibernate. I tracked down the reason in the following forum: https://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068
问题是通过 copyProperties(...) 复制到实体中的 version 属性不受 Hibernate 的尊重。我在以下论坛中找到了原因:https: //forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068
In short, when load() is called, Hibernate caches the version property in the session cache and it doesn't matter what it's value is subsequently changed to. I agree that this is the correct behavior, but I have been instructed by Bosses to pass the version via an HTML form property (if there is a better pattern for this, I'd love to hear it).
简而言之,当 load() 被调用时,Hibernate 将版本属性缓存在会话缓存中,它的值随后更改为什么并不重要。我同意这是正确的行为,但 Bosses 指示我通过 HTML 表单属性传递版本(如果有更好的模式,我很想听听)。
One solution I am exploring now is to evict the entity from the session after it's version has been set using hibernateTemplate.evict(simpleEntity) before the update happens. I hope this works, but it doesn't seem efficient.
我现在正在探索的一种解决方案是在更新发生之前使用 hibernateTemplate.evict(simpleEntity) 设置版本后从会话中驱逐实体。我希望这有效,但似乎效率不高。
I would like to ask Hibernate to check the version property on the instance itself, rather than only from the session cache.
我想请 Hibernate 检查实例本身的 version 属性,而不仅仅是从会话缓存中检查。
Thanks in advance for answers!
预先感谢您的回答!
-- LES
-- 莱斯
采纳答案by ChssPly76
Do you reallyneed to use DTO? You wouldn't have had this problem if you were passing the actual entity around - nor would you have to load the entity again, which isn't exactly great for performance.
你真的需要使用DTO吗?如果您正在传递实际实体,您就不会遇到这个问题 - 您也不必再次加载实体,这对性能来说并不是很好。
But even if you do have a legitimate reason to use DTO, I'm not quite grasping why you would try to update the version number on your freshly reloadedentity prior to saving. Consider different scenarios possible in your workflow:
但是,即使您确实有使用 DTO 的正当理由,我也不太明白为什么您会在保存之前尝试更新刚重新加载的实体的版本号。考虑工作流中可能出现的不同场景:
- Entity is loaded initially, has version = V1
- It's transferred to DTO which goes to UI, comes back and is ready to be saved.
- Entity is loaded again, has version = V2
- 实体最初加载,版本 = V1
- 它被转移到 DTO,后者进入 UI,返回并准备保存。
- 实体再次加载,版本 = V2
You have two possibilities now:
你现在有两种可能:
- V1 == V2. Peachy, you don't have to do anything.
- V1 is less than V2, meaning entity was updated by someone else while you were editing it. There's no reason to try to set version to V1 and attempt to save because saving will fail. You can either save it with V2 (thus overriding someone else's changes) or fail now.(without involving Hibernate).
- V1 == V2。桃子,你什么都不用做。
- V1 小于 V2,这意味着实体在您编辑时被其他人更新。没有理由尝试将版本设置为 V1 并尝试保存,因为保存会失败。您可以使用 V2 保存它(从而覆盖其他人的更改)或现在失败。(不涉及 Hibernate)。

