当应用程序通过new语句创建了一个对象,这个对象的生命周期就开始了,当不再有任何引用变量引用它,这个对象就结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收。对于需要被持久化的Java对象,在它的生命周期中,可处于以下三个状态之一:
(1) 临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。 (2) 持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。 (3) 游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象。
图1为Java对象的完整状态转换图,Session的特定方法触发Java对象由一个状态转换到另一个状态。从图1看出,当Java对象处于临时状态或游离状态,只要不被任何变量引用,就会结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收;当处于持久化状态,由于Session的缓存会引用它,因此它始终处于生命周期中。
临时对象的特征
临时对象具有以下特征: (1) 不处于Session的缓存中,也可以说,不被任何一个Session实例关联。 (2) 在数据库中没有对应的记录。
在以下情况下,Java对象进入临时状态: (1) 当通过new语句刚创建了一个Java对象,它处于临时状态,此时不和数据库中的任何记录对应。 (2) Session的delete()方法能使一个持久化对象或游离对象转变为临时对象。对于游离对象,delete()方法从数据库中删除与它对应的记录;对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从Session的缓存中删除。
持久化对象的特征
持久化对象具有以下特征: (1) 位于一个Session实例的缓存中,也可以说,持久化对象总是被一个Session实例关联。 (2) 持久化对象和数据库中的相关记录对应。 (3) Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。
Session的许多方法都能够触发Java对象进入持久化状态: (1) Session的save()方法把临时对象转变为持久化对象。 (2) Session的load()或get()方法返回的对象总是处于持久化状态。 (3) Session的find()方法返回的List集合中存放的都是持久化对象。 (4) Session的update()、saveOrUpdate()和lock()方法使游离对象转变为持久化对象。(nate注:根据hibernate reference的说法当试图用update更新一个持久化对象时会抛异常) (5)当一个持久化对象关联一个临时对象,在允许级联保存的情况下,Session在清理缓存时会把这个临时对象也转变为持久化对象。
Hibernate保证在同一个Session实例的缓存中,数据库表中的每条记录只对应惟一的持久化对象。例如对于以下代码,共创建了两个Session实例:session1和session2。session1和session2拥有各自的缓存。在session1的缓存中,只会有惟一的OID为1的Customer持久化对象,在session2的缓存中,也只会有惟一的OID为1的Customer持久化对象。因此在内存中共有两个Customer持久化对象,一个属于session1的缓存,一个属于session2的缓存。引用变量a和b都引用session1缓存中的Customer持久化对象,而引用变量c引用session2缓存中的Customer持久化对象:
Session session1=sessionFactory.openSession(); Session session2=sessionFactory.openSession(); Transaction tx1 = session1.beginTransaction(); Transaction tx2 = session2.beginTransaction();
Customer a=(Customer)session1.load(Customer.class,new Long(1)); Customer b=(Customer)session1.load(Customer.class,new Long(1)); Customer c=(Customer)session2.load(Customer.class,new Long(1));
System.out.println(a= =b); //true System.out.println(a= =c); //false
tx1.commit(); tx2.commit(); session1.close(); session2.close();
Java对象的持久化状态是相对于某个具体的Session实例的,以下代码试图使一个Java对象同时被两个Session实例关联:
Session session1=sessionFactory.openSession(); Session session2=sessionFactory.openSession(); Transaction tx1 = session1.beginTransaction(); Transaction tx2 = session2.beginTransaction();
Customer c=(Customer)session1.load(Customer.class,new Long(1)); //Customer对象被session1关联 session2.update(c); //Customer对象被session2关联 c.setName("Jack"); //修改Customer对象的属性
tx1.commit(); //执行update语句 tx2.commit(); //执行update语句 session1.close(); session2.close();
当执行session1的load()方法时,OID为1的Customer对象被加入到session1的缓存中,因此它是session1的持久化对象,此时它还没有被session2关联,因此相对于session2,它处于游离状态。当执行session2的update()方法时,Customer对象被加入到session2的缓存中,因此也成为session2的持久化对象。接下来修改Customer对象的name属性,会导致两个Session实例在清理各自的缓存时,都执行相同的update语句:
update CUSTOMERS set NAME='Jack' …… where ID=1; 在实际应用程序中,应该避免一个Java对象同时被多个Session实例关联,因为这会导致重复执行SQL语句,并且极容易出现一些并发问题。
游离对象的特征
游离对象具有以下特征: (1) 不再位于Session的缓存中,也可以说,游离对象不被Session关联。 (2) 游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录(前提条件是没有其他程序删除了这条记录)。
游离对象与临时对象的相同之处在于,两者都不被Session关联,因此Hibernate不会保证它们的属性变化与数据库保持同步。游离对象与临时对象的区别在于:前者是由持久化对象转变过来的,因此可能在数据库中还存在对应的记录,而后者在数据库中没有对应的记录。
Session的以下方法使持久化对象转变为游离对象: (1) 当调用Session的close()方法时,Session的缓存被清空,缓存中的所有持久化对象都变为游离对象。如果在应用程序中没有引用变量引用这些游离对象,它们就会结束生命周期。 (2)Session的evict()方法能够从缓存中删除一个持久化对象,使它变为游离状态。当Session的缓存中保存了大量的持久化对象,会消耗许多内存空间,为了提高性能,可以考虑调用evict()方法,从缓存中删除一些持久化对象。但是多数情况下不推荐使用evict()方法,而应该通过查询语言,或者显式的导航来控制对象图的深度。
|
相关推荐
域对象在持久化层的状态
名词解释,高内聚,低偶合,OSWorkflow,Hibernate 持久化层的游离状态
毕业设计、课程设计、大作业——微信小程序奶茶下单系统,前后端分离,Json通信,Springboot后端,,持久层mybatis。 技术栈 客户端 微信小程序 后台前端 React,Ant组件库 后台后端 SpringBoot,Mysql 四.具体...
Shift为简单的“有限状态机”域模型提供了SQL持久层。 它根据状态变化提供验证,显式字段和反射事件。 因此,它用于显式定义域模型的生命周期,即它可以转换的状态以及每次转换所需的数据修改。 概述 移位状态机由...
redux-storage, 带有灵活后端的redux持久层 redux存储库 轻松保存和加载 Redux 状态。移动到响应堆栈组织我的重点离开了 node/react 生态系统,这个模块在响应堆栈了一个新的主页。特性灵活的存储引擎localStorag
环境:Window XP profession, JDK 1.6, MySQL 5.0, JBoss...该示例使用EJB 3.0的无状态会话Bean呼叫JPA持久层完成数据库的操作,推荐广大企业级Java程序员项目中使用。 注意:连接池的配置参见上一个资源readme.txt文档
本章站在持久化层的角度,Java对象在生命周期中可处于临时状态、持久化状态、删除状态和游离状态。处于持久化状态的Java对象位于一个Session实例的缓存中,Session能根据这个对象的属性变化来同步更新数据库。 8.1 ...
本章站在持久化层的角度,Java对象在生命周期中可处于临时状态、持久化状态、删除状态和游离状态。处于持久化状态的Java对象位于一个Session实例的缓存中,Session能根据这个对象的属性变化来同步更新数据库。 8.1 ...
更可扩展的,灵活的,可测试分析持久层Sitecore的,与Elasticsearch实现出货。 嗯...那是目标。 在它的当前状态,这将持续存在,Elasticsearch加载Sitecore的接触,但没有数据访问组件的所有方法都已经实现(将...
如果大量的 Time_wait ...使用 TCP Keepalive:TCP Keepalive 可以在服务器端和客户端之间建立持久连接,避免连接断开后导致的 TIME_WAIT 状态。 使用传输层网关:传输层网关可以代替服务器端和客户端之间的直接连接,
不再强制开发者在持久层捕捉异常,持久层异常被包装成DataAccessException,底层数据库异常包装成业务异常。开发者可以自己决定在合适的层处理。 HibernateTemplate支持类。可以完成大量Hibernate持久层的操作。 ...
灯光由单独的进程(原始Python API仅允许通过单个进程进行操作,因为设备本身是只写的,并且灯光状态仅存储为全局变量)。 该API仅使用内部缓存来存储设备状态并在每次执行脚本时将其恢复。 效率不高,但是可以完成...
BPM,全称是Java Business Process ...Hibernate是目前Java领域最好的一种数据持久层解决方案。通过Hibernate,jBPM将数据的管理职能分离出去,自己专注于商务逻辑的处理。 说不如做,下面做个例子感受以下吧。
8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的特征 8.3.3 被删除对象的特征 8.3.4 游离对象的特征 8.4 Session接口的详细用法 8.4.1 Session的save()和persist()...
jBPM,全称是Java Business ...Hibernate是目前Java领域最好的一种数据持久层解决方案。通过Hibernate,jBPM将数据的管理职能分离出去,自己专注于商务逻辑的处理。 http://zhidao.baidu.com/question/8510654.html
轻松保存和加载状态。 产品特点 灵活的存储引擎 :基于window.indexedDb :基于window.localStorage 或对于没有Promise支持的环境 :基于react-native/AsyncStorage :通过XHR保存/加载 灵活的州合并功能 :合并...
下面说xmpp类的作用 XmppConnectionListerner是xmpp的连接状态的listener,比如断线等XmppMessageInterceptor是发出消息的listener,在此拦截并持久化聊天纪录XmppMessageListener是收到消息的listener,在此拦截并...
持久性日志 此Golang包实现的持久性日志非常类似于数据库重播日志或预写日志(WAL):在对资源(任意数据结构)进行更改之前,应用程序将资源的新状态写入日志。...此持久层不能执行的某些操作: 多资源更新
分析-数据持久层定义及优点 分析-数据持久层技术分类 分析-文件系统和关系型数据库 分析-状态图和活动图定义与区别 关系模式 关系运算-比较 管理信息系统规划的方法 架构描述语言-ADL 架构权衡分析方法 路由-层次化 ...