Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在前端使用Hibernate乐观锁定版本属性?_Java_Hibernate_Web Applications_Optimistic Locking - Fatal编程技术网

Java 如何在前端使用Hibernate乐观锁定版本属性?

Java 如何在前端使用Hibernate乐观锁定版本属性?,java,hibernate,web-applications,optimistic-locking,Java,Hibernate,Web Applications,Optimistic Locking,使用实体的版本属性进行乐观锁定效果良好,易于实现: <version property="VERSION" type="int" column="EX_VERSION" /> 到目前为止,一切顺利。现在,服务方法为上面的实体返回一个数据传输对象(DTO),视图以HTML显示。对于更新页面,版本属性存储在HTML隐藏字段中,并随表单一起提交 其目的是使用version属性确保如果显示的信息附带旧版本,则用户的更新将失败 控制器通过使用包含更新信息(包括版本属性)的DTO调用服务方法来

使用实体的版本属性进行乐观锁定效果良好,易于实现:

<version property="VERSION" type="int" column="EX_VERSION" />
到目前为止,一切顺利。现在,服务方法为上面的实体返回一个数据传输对象(DTO),视图以HTML显示。对于更新页面,版本属性存储在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);
}
问题在于,Hibernate不遵守copyProperties(…)复制到实体中的version属性。我在以下论坛中找到了原因:

简而言之,在调用load()时,Hibernate会将version属性缓存在会话缓存中,它的值随后更改为什么并不重要。我同意这是正确的行为,但老板已经指示我通过HTML表单属性传递版本(如果有更好的模式,我很乐意听到)

我现在正在探索的一个解决方案是,在更新之前,在使用hibernateTemplate.execit(simpleEntity)设置实体的版本之后,从会话中逐出实体。我希望这能奏效,但似乎效率不高

我想让Hibernate检查实例本身的version属性,而不仅仅是从会话缓存中检查

提前感谢您的回答

--
LES

你真的需要使用DTO吗?如果传递实际实体,则不会出现此问题,也不必再次加载实体,这对性能来说并不太好

但是,即使您确实有合理的理由使用DTO,我也不太明白为什么您会在保存之前尝试更新新加载的实体上的版本号。考虑工作流中可能出现的不同场景:

  • 初始加载实体,版本=V1
  • 它被传输到DTO,DTO进入UI,返回并准备保存
  • 再次加载实体,其版本=V2
  • 您现在有两种可能性:

  • V1==V2。桃子,你什么都不用做
  • V1小于V2,这意味着实体是在您编辑它时由其他人更新的。没有理由尝试将版本设置为V1并尝试保存,因为保存将失败。您可以使用V2保存它(从而覆盖其他人的更改),也可以立即失败(不涉及Hibernate)

  • 从会话中逐出实体()有效。:)留下来看看是否有我深刻的答案…1。可能需要重新加载,因为DTO可能不完全包含所有实体字段,只包含一个子集。2.正如所评论的(也可以在文章底部的链接中阅读),execute可以在这里提供帮助。
    public void update(SimpleDTO dto) {
        SimplyEntity entity = getSimpleDao().load(dto.getId());
        copyProperties(dto, entity); // all properties, including VERSION copied to entity
        getSimpleDao().update(entity);
    }