目录
瞬时态→持久态:Session的save()或saveOrUpdate()方法
持久态→脱管态:执行evict()、close()或clear()
脱管态→持久态:Session的update()、saveOrUpdate()以及lock()方法
脱管态→瞬时态:将脱管态对象的持久化标识OID设置为null
持久化对象三种状态
Hibernate为了更好的管理持久化类,特将持久化类分成了三种状态。在Hibernate中持久化的对象可以划分为三种状态
-
瞬时态(transient)
瞬时态也称为临时态或者自由态,瞬时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session关联,在数据库中也没有记录,失去引用后将被JVM回收。瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无任何关联,仅是一个信息携带的载体
-
持久态(persistent)
持久态的对象存在持久化标识OID,加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久化对象时在事物还未提交前变成持久态的
-
脱管态(detached)
脱管态也称力离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管态对象发生改变时,Hibernate不能检测到
三种状态区分
customer对象由new关键词创建,此时还未与Session进行关联,它的状态称为瞬时态;在执行了session.save(customer)操作后,book对象纳入了Session的管理范围,这时的customer对象变成了持久态对象,此时Session的事务还没有被提交;程序执行完commit()操作并关闭了Session后,customer对象与Session的关联被关闭,此时customer对象就变成了脱管态
@Test
public void test(){
Session session = HibernateUtil.openSession();
Transaction trans = session.beginTransaction();
Customer customer = new Customer(); //瞬时态对象:没有持久化标识OID,没有被session管理
customer.setCust_name("mark");
Serializable id = session.save(customer); //持久态对象:有持久化标识OID,被session管理
trans.commit();
session.close();
System.out.println(customer); //脱管态对象:有持久化标识OID,没有被session管理
}
三种状态转换
三种状态之间是可以相互转换的
从上图可以看出,当一个对象被执行了new关键字创建后,该对象处于瞬时态;当对瞬时态对象执行Session的save()或saveOrUpdate()方法后,该对象将被放入Session的一级缓存,对象进入持久态;当对持久态对象执行evict()、close()或clear()操作后,对象进入脱管态;当直接执行Session的get()、load()、find()或iterate()等方法从数据库里查询对象时,查询到的对象也处于持久态;当对数据库中的记录进行update()、saveOrUpdate()以及lock()等操作后,此时脱管态的对象就过渡到持久态;由于瞬时态和脱管态的对象不再session的管理范围,所以会在一段时间后被JVM回收
saveOrUpdate()方法,可以无脑地将瞬时态或者脱管态转换成持久态,持久化对象的三种状态可以通过调用Session中的一系列方法实现状态间的转换
-
瞬时态→其他状态
瞬时态→持久态:Session的save()或saveOrUpdate()方法
瞬时态→脱管态:为瞬时态对象设置持久化标识OID
瞬时态和托管态的区别就是OID有没有值,所以可以通过为瞬时态对象设置OID,使其变成托管态对象
Customer customer = new Customer(); //瞬时态:没有持久化标识OID,没有被session管理
customer.setCust_id(1); //脱管态:有持久化标识OID,没有被session管理
-
持久态→其他状态
持久态对象可以直接通过Hibernate中Session的get()、load()方法,或者Query查询从数据库中获得
持久态→瞬时态:Session的delete()
被删除的持久化对象,不建议再次使用
持久态→脱管态:执行evict()、close()或clear()
evict()方法用于清除一级缓存中某一个对象;close()方法用关闭Session,清除一级缓存;clear()方法用于清除一级缓存中的所有对象
-
脱管态→其他状态
脱管状态无法直接获得,是由其他状态对象转换而来的
脱管态→持久态:Session的update()、saveOrUpdate()以及lock()方法
被删除的持久化对象,不建议再次使用
脱管态→瞬时态:将脱管态对象的持久化标识OID设置为null
瞬时态和托管态的区别就是OID有没有值,所以可以通过为脱管态对象设置OID为null,使其变成瞬时态对象
session.close(); //脱管态:有持久化标识OID,没有被session管理
customer.setCust_id(null); //瞬时态:没有持久化标识OID,没有被session管理
持久态对象能够自动更新数据库
持久态对象能够依赖Hibernate的一级缓存,来使持久态对象自动更新数据,不用手动调用update方法即可更新
public void test() {
Session session = HibernateUtil.openSession();
Transaction trans = session.beginTransaction();
//获得持久态对象
Customer customer = session.get(Customer.class, 10L);// 持久态对象
customer.setCust_name("mark");
// session.update(customer); // 不用手动调用update方法就可以更新
trans.commit();
session.close();
}