使用实体的版本属性的乐观锁定工作正常并且易于实现:
<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 隐藏字段中并与表单一起提交。
目的是使用 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);
}
问题是通过 copyProperties(...) 复制到实体中的版本属性不受 Hibernate 的尊重。我在以下论坛中找到了原因:https ://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068
简而言之,当调用 load() 时,Hibernate 将 version 属性缓存在 session 缓存中,随后将其值更改为什么都没有关系。我同意这是正确的行为,但是 Bosses 指示我通过 HTML 表单属性传递版本(如果有更好的模式,我很想听听)。
我现在正在探索的一种解决方案是在更新发生之前使用 hibernateTemplate.evict(simpleEntity) 设置它的版本后从会话中逐出实体。我希望这可行,但似乎效率不高。
我想要求 Hibernate 检查实例本身的版本属性,而不仅仅是从会话缓存中。
提前感谢您的回答!
-- LES