如果在映射时,定义了 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 的值是否正确了。
分享到:
相关推荐
在Java开发中,数据持久化是将应用程序中的对象状态保存到数据库中的过程,以便在后续的程序运行中可以恢复这些状态。Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了这个过程。本章节我们将深入探讨...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
### 属性容器类的对象持久化 #### 1. 问题背景与提出 在软件开发过程中,经常遇到需要处理各种文档管理的问题。一个典型的场景是构建一个文档管理系统,该系统能够支持不同类型的文档,并且每种文档可能具有不同的...
- Detached(游离):持久化对象在Session关闭后,就会变为游离状态。这时,对象与Session断开,但其仍然包含数据库中的数据副本。更新游离状态对象不会直接影响数据库,除非调用特定的更新方法。 2. Hibernate的...
在 Eclipse 中搭建 Hibernate 项目环境步骤 在本文中,我们将详细介绍如何在 Eclipse 中搭建 Hibernate 项目环境的步骤。Hibernate 是一个流行的 Java 持久层框架,提供了对数据库的访问和操作功能。通过本文,读者...
这个库通常与Hibernate一起使用,以实现更高级别的数据持久化操作。 另外,还有一些以`dialect`结尾的jar文件,如`hibernate-5.0.12.Finaldialect.jar`,这些通常是针对特定数据库的方言(Dialect)实现,用于告诉...
- 在Hibernate中,持久化对象经历瞬态(Transient)、持久化(Persistent)、托管(Managed)和脱管(Detached)四个状态,它们描述了对象在内存和数据库之间的关系。 四、Hibernate中实体关系的处理 - Hibernate...
- Hibernate提供了对象持久化的机制,能够将对象的状态保存到数据库中,同时也能从数据库中读取对象。 - 它允许开发者通过Java API与数据库交互,而不需要直接编写SQL语句。 - Hibernate的缓存机制可以提高数据访问...
这个类称为实体类或持久化类,它的实例称为实体对象或持久化对象。例如: ```java package com.asm.hibernate.domain; public class User { private int id; private String name; private Date date; // ...
10. **懒加载与即时加载**:为了性能优化,Hibernate提供了懒加载机制,只有在实际需要时才会加载关联对象,而即时加载则会在加载主体对象时同时加载关联对象。 11. **版本控制与乐观锁**:Hibernate通过`@Version`...
- 对象持久化:将Java对象的状态持久化存储到数据库中。 - 支持多种数据库:通过不同的数据库方言配置,Hibernate可以很好地与多种关系型数据库进行集成。 - 代码简洁性:使用Hibernate可以减少大量的SQL语句编写...
<hibernate-mapping package="持久化对象所在的包路径"> 对应的持久化对象名" table="对应数据库中的表名"> 数据库中表的主键名所对应的持久化对象中的属性名" column="对应数据库中表的主键名" type="java.lang...
3. **支持面向对象编程**:Hibernate支持Java对象的缓存机制,使得对象的持久化更加自然,符合面向对象的编程思想。 #### 三、何时使用Hibernate? 1. 当项目中有明确的对象模型设计时,使用Hibernate能够充分发挥...
Hibernate是一个流行的Java持久化框架,它简化了数据库操作,使得开发者能够更方便地管理和操作数据库。Maven仓库是Java开发中获取依赖库的重要途径,这里提到的是Hibernate相关的依赖资源。 **描述解析:**描述中...
Hibernate根据对象与数据库记录的状态将其分为瞬时、持久化、托管和脱管四种状态。EntityPersister和AbstractEntityTuplizer等类负责实体的管理,理解这些状态转换机制对于理解对象的生命周期至关重要。 6. **缓存...
Hibernate是由 Gavin King 创建的一个开源项目,它实现了JPA(Java Persistence API)规范,提供了一种在Java应用中持久化对象的机制。通过Hibernate,我们可以避免编写大量的SQL语句,而是通过定义对象和数据库表...
例如,如果你有一个User类,添加@Entity注解后,Hibernate会知道这个类需要被持久化到数据库中。 接着,@Table注解用于指定实体Bean映射的具体数据库表。例如,@Table(name = "users")将会把User类映射到名为users...
它的主要功能包括:持久化对象、事务管理、查询语言(HQL)和缓存机制。 2. **环境准备** 在安装Hibernate之前,确保已安装以下软件: - Java Development Kit (JDK):Hibernate需要Java环境支持,所以首先要安装...