如何在前端使用Hibernate乐观锁定版本属性? [英] How to use the Hibernate optimistic locking version property on the front end?

查看:277
本文介绍了如何在前端使用Hibernate乐观锁定版本属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用版本属性为实体进行乐观锁定可以正常工作,并且很容易实现:

 < version property = VERSIONtype =intcolumn =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); //所有属性,包括复制到实体
getSimpleDao()。update(entity);
}

问题在于版本属性通过copyProperties(..)复制到实体中。 )不受Hibernate的尊重。我在以下论坛中追查了原因: https:/ /forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068



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



我现在研究的一个解决方案是在更新发生之前使用hibernateTemplate.evict(simpleEntity)设置版本后,从会话中逐出实体。我希望这可以工作,但效果并不理想。



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



预先感谢您的解答!

-
LES

解决方案

您真的需要使用DTO吗?如果您传递的是实际的实体,则不会有这个问题 - 也不需要再次加载该实体,这对性能来说并不太好。



但即使您确实有使用DTO的合法理由,但我并没有完全理解为什么您要在保存之前更新刚刚重新加载的实体的版本号。请考虑您的工作流程中可能出现的不同情况:


  1. 实体最初加载,版本= V1
  2. 它被转移到DTO,转到UI,返回并准备保存。
  3. 实体再次加载,版本= V2

现在有两种可能性:


  1. V1 == V2。 Peachy,你不需要做任何事。

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

    Optimistic locking using the version attribute for an entity works fine and is easy to implement:

    <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.

    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.

    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:

    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

    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).

    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.

    I would like to ask Hibernate to check the version property on the instance itself, rather than only from the session cache.

    Thanks in advance for answers!

    -- LES

    解决方案

    Do you really need 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.

    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 reloaded entity prior to saving. Consider different scenarios possible in your workflow:

    1. Entity is loaded initially, has version = V1
    2. It's transferred to DTO which goes to UI, comes back and is ready to be saved.
    3. Entity is loaded again, has version = V2

    You have two possibilities now:

    1. V1 == V2. Peachy, you don't have to do anything.
    2. 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).

    这篇关于如何在前端使用Hibernate乐观锁定版本属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆