代码之家  ›  专栏  ›  技术社区  ›  les2

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

  •  12
  • les2  · 技术社区  · 17 年前

    <version property="VERSION" type="int" column="EX_VERSION" />
    

    该实体具有以下类型的属性:

    private int VERSION;
    public int getVERSION() { return VERSION; }
    public void setVERSION(int VERSION) { this.VERSION = VERSION; }
    

    其目的是使用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属性。我在以下论坛中找到了原因: https://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068

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

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

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

    提前感谢您的回答!

    -- 发射脱离系统

    1 回复  |  直到 17 年前
        1
  •  11
  •   ChssPly76    17 年前

    你…吗 真正地

    但是,即使您确实有合理的理由使用DTO,我也不太明白您为什么要尝试更新您的计算机上的版本号 新装的

    1. 初始加载实体,版本=V1
    2. 它被传输到DTO,DTO进入UI,返回并准备保存。
    3. 再次加载实体,其版本=V2

    您现在有两种可能性:

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