`

hibernate在什么时候才会去检测持久化对象的version?

阅读更多

如果在映射时,定义了 optimistic-lock=”version”,同时映射了  <version name=”version” type=”integer” unsaved-value=”negative”/>,那么就会起用hibernate的乐观锁机制。hibernate会在执行update merge等更新操作时对比数据库里的该行的version和当前对象的version是否一样,如果一样则更新,不一样则出异常。但是 hibernate并不会在所有的更新操作时都做去对比这个version。

乐观锁是用来处理并发事务的。如果有多个事物同时对一行数据进行更新,那么才会检测这个version;反之,如果在一个事务内部,无论对 version做怎么样的更改,都不会检测。那么hibernate是如何做到这一步的呢?在每个事务提交的时候,hibernate会判断当前事务里有哪些对象被更新到数据库里,如果这个对象处理持久化状态,则不检查它的version,如果处于游离态,则要在更新前检查version。

换句话说,如果对象是在当前的事物里通过load方法,get方法,或者通过query等查询出来的,那么这个对象在当前事物里处于持久化状态,hibernate 就不会检测version。如果对象不是在当前事务中被从数据库中读出来的,而是程序新建,或者是前一个事务或前一个session里取出来的,那么在当前事务里它就处于游离态,hibernate就会检version。

例如,有一个类Person,需要更新属性name。于你查出这个对象把这个对象在页面显示,并且让用户在页面上更改完成并提交时,form里包含那个对象的id,要更新的字段name和version。这样当用户提交后,在后台,如果你是这样做的:

//……

Transaction transaction = session.beginTransaction();

Person person = (Person) session.load( Person.class, id);

person.setName(name);

person.setVersion(version);

session.update(person);

transaction.commit();

//……

上面那种情况,因为被update的person是从当前事务中查询出来的,正处于持久化状态,所以在更新时,就算页面传来的version值比前数据库里的version值小,hibernate也不会报错,因为它根本就不会检测。如果想让hibernate检测,你可以这样做:

//……

Transaction transaction = session.beginTransaction();

Person person = new Person();

person.setId(id);

person.setName(name);

person.setVersion(version);

session.update(person);

transaction.commit();

//……

由于是新建出来的person,这时的person处于游离态,所以在后面的更新时,hibernate就会按照你的意愿去检测version 了。

但是上面的方法还是有问题,就是如果那个Person里有很多个属性,而你只要改其中一部分,如果你不把所有的属性都扔到页面上,再在回来时写入新建的person里,那么在更新时,很可能会就会把一些你不想被更新字段给覆盖掉。而且,如果person和其它对象有外键关联,就更麻烦了。在这样的情况下,还是从数据库里取出当前对象,并更新它的那几个字段来得方便,不过这个时候如果你真的需要检测version,估计只好手动判断version 的值是否正确了。
分享到:
评论

相关推荐

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    hibernate配置

    &lt;hibernate-mapping package="持久化对象所在的包路径"&gt; 对应的持久化对象名" table="对应数据库中的表名"&gt; 数据库中表的主键名所对应的持久化对象中的属性名" column="对应数据库中表的主键名" type="java.lang...

    hibernate 3中的缓存小结

    当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级...

    Hibernate+中文文档

    10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.2. 过滤集合 10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 ...

    Hibernate 中文API文档

    Hibernate的目标是对于开发者通常的数据持久化相关的编程任务,解放其中的95%。对于以数据为中心的程序来说,它们往往只在数据库中使用存储过程来实现商业逻辑,Hibernate可能不是最好的解决方案;对于那些在基于Java的...

    HibernateAPI中文版.chm

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    hibernate 教程

    创建一个持久化对象 9.2. 装载对象 9.3. Querying 9.3.1. 标量查询(Scalar query) 9.3.2. 查询接口(Query interface) 9.3.3. 可滚动迭代(Scrollable iteration) 9.3.4. 过滤集合类(Filtering...

    hibernate3.2中文文档(chm格式)

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    Hibernate教程

    11.2. 使对象持久化 11.3. 装载对象 11.4. 查询 11.4.1. 执行查询 11.4.1.1. 迭代式获取结果(Iterating results) 11.4.1.2. 返回元组(tuples)的查询 11.4.1.3. 标量(Scalar)结果 11.4.1.4. 绑定参数 11.4....

    最全Hibernate 参考文档

    10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)结果 10.4.1.4. 绑定参数 10.4.1.5. 分页 ...

    Hibernate中文详细学习文档

    符合Java习惯的关系数据库持久化 前言 1. 翻译说明 2. 版权声明 1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. ...

    Hibernate 中文 html 帮助文档

    10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)结果 10.4.1.4. 绑定参数 10.4.1.5. 分页 ...

    hibernate 体系结构与配置 参考文档(html)

    使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)结果 10.4.1.4. 绑定参数 10.4.1.5. ...

    hibernate

    创建一个持久化对象 9.2. 装载对象 9.3. Querying 9.3.1. 标量查询(Scalar query) 9.3.2. 查询接口(Query interface) 9.3.3. 可滚动迭代(Scrollable iteration) 9.3.4. 过滤集合类(Filtering...

    Hibernate注释大全收藏

    上述代码中 counter, lengthInMeter 属性将忽略不被持久化,而 firstname, name, length 被定义为可持久化和可获取的。 @TemporalType.(DATE,TIME,TIMESTAMP) 分别Map java.sql.(Date, Time, Timestamp). @Lob ...

    Hibernate3的帮助文档

    11.2. 使对象持久化 11.3. 装载对象 11.4. 查询 11.4.1. 执行查询 11.4.1.1. 迭代式获取结果(Iterating results) 11.4.1.2. 返回元组(tuples)的查询 11.4.1.3. 标量(Scalar)结果 11.4.1.4. 绑定参数 11.4....

    hibernate3.04中文文档.chm

    符合Java习惯的关系数据库持久化 目录 前言 1. 翻译说明 2. 版权声明 1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 ...

    Hibernate3+中文参考文档

    10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)结果 10.4.1.4. 绑定参数 10.4.1.5. 分页 ...

    hibernate 框架详解

    使对象持久化 11.3. 装载对象 11.4. 查询 11.4.1. 执行查询 11.4.1.1. 迭代式获取结果(Iterating results) 11.4.1.2. 返回元组(tuples)的查询 11.4.1.3. 标量(Scalar)结果 11.4.1.4. 绑定参数 11.4.1.5. ...

    Hibernate参考文档

    10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)结果 10.4.1.4. 绑定参数 10.4.1.5. 分页 ...

Global site tag (gtag.js) - Google Analytics