les*_*es2 12 java hibernate web-applications optimistic-locking
使用实体的version属性进行乐观锁定工作正常并且易于实现:
<version property="VERSION" type="int" column="EX_VERSION" />
Run Code Online (Sandbox Code Playgroud)
该实体具有以下类型的属性:
private int VERSION;
public int getVERSION() { return VERSION; }
public void setVERSION(int VERSION) { this.VERSION = VERSION; }
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.现在,服务方法返回上面实体的数据传输对象(DTO),视图以HTML格式显示.对于更新页面,VERSION属性存储在HTML隐藏字段中并随表单一起提交.
目的是使用version属性来确保如果显示的信息附带旧版本,则用户的更新将失败.
控制器通过调用包含更新信息(包括版本属性)的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);
}
Run Code Online (Sandbox Code Playgroud)
问题是Hibernate不遵守copyProperties(...)复制到实体中的版本属性.我在下面的论坛中找到了原因:https://forum.hibernate.org/viewtopic.php?f = 1&t = 955893&p = 2418068
简而言之,当调用load()时,Hibernate会在会话缓存中缓存version属性,并且随后更改为它的值无关紧要.我同意这是正确的行为,但我已经被老板指示通过HTML表单属性传递版本(如果有更好的模式,我很乐意听到它).
我现在正在探索的一个解决方案是在更新发生之前使用hibernateTemplate.evict(simpleEntity)设置版本之后将实体从会话中逐出.我希望这有效,但它看起来效率不高.
我想请Hibernate检查实例本身的version属性,而不是仅查看会话缓存.
提前谢谢你的答案!
- LES
Chs*_*y76 11
你真的需要使用DTO吗?如果你传递实际的实体,你不会遇到这个问题 - 你也不必再次加载实体,这对性能来说并不是很好.
但即使您确实有合理的理由使用DTO,我也不太了解为什么在保存之前尝试更新新重新加载的实体的版本号.考虑工作流程中可能的不同方案:
你现在有两种可能性:
归档时间: |
|
查看次数: |
14830 次 |
最近记录: |