- 临时状态(transient):刚刚用new语句创建,没有被持久化,不处于session中。该对象成为临时对象
- 持久化状态(persistent):已经被持久化,加入到session的缓存中。该状态的对象为持久化对象。
- 游离状态(detached):已经被持久化,但不处于session中。该状态的对象为游离对象。
程序代码 | 生命周期 | 状态 |
tx = session.beginTransaction(); Customer c = new Customer(“Tom”,new HashSet); | 开始生命周期 | 临时状态 |
Session.save(c) | 处于生命周期中 | 转变为持久化状态 |
Long id=c.getId(); c = null; Customer c2 = (Customer)session.load(Customer.class,id); tx.commit(); | 处于生命周期中 | 处于持久化状态 |
session.close(); | 处于生命周期中 | 转变为游离态 |
c2,getName(); | 处于生命周期中 | 处于游离态 |
c2 = null; | 结束生命周期 | 结束生命周期 |
1、临时对象特征
不处于session中,不被任何session关联。数据库中没有对应的记录。以下情况,对象进入临时状态:
(1).new 语句刚创建了一个对象。
(2).session的delete方法使持久化对象或游离对象转变为临时对象,对于游离对象,该方法从数据库中删除记录,对于持久化对
象,该方法从数据库中删除记录,还要删除缓存中的对象。
(1)、位于一个session缓存中,总是被一个session关联。(2)、持久化对象和数据库记录相对应。(3)、以下情况,对象进入持久化:
清理缓存时,会根据对象属性变化,同步更新数据库。save把临时对象转变为持久化对象。load或get返回的对象总是持久化状态。query接口方法返回的list存放的都是持久化对象。update、save、saveOrUpdate和LockRequest.lock方法使游离对象转变为持久化对象。
在实际的应用程序中应该避免一个java对象被多个session实例关联,会导致重复执行sql语句,并且极容易出现一些并发问题。
3、游离对象特征
(1).sesson.close()方法使缓存被清空,缓存中的所有的对象都变为游离对象。如果没有引用他们的话,他们就会结束生命周期。
(2).sesson.evict(Object args)方法从缓存中删除一个持久化对象,使他变为游离态对象。当缓存中保存了大量的持久化对象时,会消耗许多内存空间,使用该方法删掉一些对象来节省空间。
对象的生命周期及转换方法如图所示:
4、Session的增、删、改、查方法:
save(Objectargs):
1.对象加入缓存,成为持久化对象。
2.为持久化对象分配OID。
update(Objectargs):
将游离对象转变为持久化对象。不论对象属性是否发生变化,该方法都会执行update操作。如果希望仅当属性变化时才执行update语句的话可进行如下配置:
<class name=“”table=“” select-before-update=“true”>
load和get:
从数据库加载指定的OID持久化对象。如果数据库中不存在该记录时,load方法会抛出异常,而get方法返回null。load是延迟加载,get是立刻加载。
delete(Objectargs):
如果参数是持久化对象,就执行一个delete语句,若为游离对象,先使游离对象被session关联,使他变为持久化对象,然后计划执行一个delete语句。
saveOrUpdate(Objectargs):
该方法同时包含save和update方法,如果参数是临时对象就用save方法,如果是游离对象就用update方法,如果是持久化对象就直接返回。
临时对象判断法:
(1).Java对象的OID为null
(2).Java对象具有version属性并取值为null
(3).在映射文件中为<id>元素设置了unsaved-value属性,并且OID属性取值与属
性匹配。
(4).在映射文件中为<version>元素设置了unsaved-value属性,并且version属性取
值与属性匹配。
(5).自定义了hibernate的Interceptor实现类,并且Interceptor 的isUnsaved方法返回Boolean.true,如果id的类型为long,则默认值为0,此时需要在配置文件中设置id的unsaved-value为0。