version(版本号)
版本号配置中须指明 optimistic-lock="version"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.Student" table="student" optimistic-lock="version">
<id name="id" column="id" type="string">
<generator class="uuid"></generator>
</id>
<version name="version" column="version" type="integer"></version>
<property name="cardId" column="cardId" type="string"></property>
<property name="age" column="age" type="integer"></property>
<property name="name" column="name" type="string"></property>
</class>
</hibernate-mapping>
在测试类HibernateTest中session1会话查询修改student表后, 如果session2会话中再对student表进行修改,此时会抛出org.hibernate.StaleObjectStateException异常,意思是说第一次修改后表中version的值会由0变为1(表中version的初始值为0),当第二次尝试进行修改的时候底层会将查询时获得version(值为0)与数据库中一更新的值为1的version进行对比,发现0 < 1 便会抛出以上异常(大概是过期的类状态异常的意思)。
HibernateTest类代码如下:
package com.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateTest {
private static SessionFactory sessionFactory;
static
{
try
{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
// Student student = new Student();
// student.setName("zhangsan");
// student.setAge(20);
// student.setCardId("14");
// session.save(student);
// tx.commit();
Session session1 = sessionFactory.openSession();
Session session2 = sessionFactory.openSession();
Student student1 = (Student)session1.createQuery("from Student s where s.name = :name").setString("name", "zhangsan").uniqueResult();
Student student2 = (Student)session2.createQuery("from Student s where s.name = :name").setString("name", "zhangsan").uniqueResult();
System.out.println(student1.getVersion());
System.out.println(student2.getVersion());
Transaction tx1 = session1.beginTransaction();
student1.setName("lisi");
tx1.commit();
System.out.println(student1.getVersion());
System.out.println(student2.getVersion());
Transaction tx2 = session2.beginTransaction();
student2.setCardId("111");
tx2.commit();
System.out.println(student1.getVersion());
System.out.println(student2.getVersion());
}
catch(Exception ex)
{
ex.printStackTrace();
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
}
}
对应的控制台的输出信息如下:
Hibernate:
select
student0_.id as id0_,
student0_.version as version0_,
student0_.cardId as cardId0_,
student0_.age as age0_,
student0_.name as name0_
from
student student0_
where
student0_.name=?
Hibernate:
select
student0_.id as id0_,
student0_.version as version0_,
student0_.cardId as cardId0_,
student0_.age as age0_,
student0_.name as name0_
from
student student0_
where
student0_.name=?
0
0
Hibernate:
update
student
set
version=?,
cardId=?,
age=?,
name=?
where
id=?
and version=?
1
0
Hibernate:
update
student
set
version=?,
cardId=?,
age=?,
name=?
where
id=?
and version=?
<span style="color:#ff0000;">org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.hibernate.Student#ef3262e84974c56c014974c56dc60000]</span>
timestamp(时间戳)
时间戳配置中无须指明optimistic-lock参数
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.Student" table="student">
<id name="id" column="id" type="string">
<generator class="uuid"></generator>
</id>
<timestamp name="lastDate" column="lastDate"></timestamp>
<property name="cardId" column="cardId" type="string"></property>
<property name="age" column="age" type="integer"></property>
<property name="name" column="name" type="string"></property>
</class>
</hibernate-mapping>
对于timestamp的测试方法与version原理方法基本一样,大家可以自己尝试一下,谢谢!