hibernate中有三种状态:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。

本文主要是介绍hibernate中有三种状态:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在hibernate中有三种状态:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object)。
通过自己在网上的搜索,也了解到,这三种状态也可以称作:临时状态、持久状态、游离状态。
一、三种状态介绍:
(1) 瞬时状态:
由new操作符创建,且尚未与Hibernate Session关联的对象被认定为瞬时(Transient)的。瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁。使用Hibernate Session可以将其变为持久(Persistent)状态。(Hibernate会自动执行必要的SQL语句)。
瞬时状态的特点有:
1、 与数据库中的记录没有任何关联,也就是没有与其相关联的数据库记录。
2、 与Session没有任何关系,也就是没有通过Session对象的实例对其进行任何持久化的操作。

举例:
User user=new User();      //user是一个瞬时对象,在数据库的表中是没有记录和该对象相对应的。和session没有关系。
user.setName(“ddd”);
user.setBirthday(new Date());

session.save(user); //持久化状态



(2) 持久状态:
持久(Persistent)是实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)。持久(Persistent)的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。Hibernate会检测到处于持久(Persistent)状态的对象的任何改动,在当前操作单元(unit of work)执行完毕时将对象数据(state)与数据库同步(synchronize)。开发者不需要手动执行Update。将对象从持久(Persistent)状态编程瞬时(Transient)状态同样也不需要手动执行delete语句。
持久对象具有如下特点:
1、 和session实例关联;
2、 在数据库中有与之关联的记录。
3、 Hibernate会根据持久态对象的属性的变化而改变数据库中的相应记录。
举例:
Session session = factory.openSession();    
        Transaction tx = session.beginTransaction();    
   
        session.save(stu); // persistent持久化状态    
        System.out.println(stu);    
   
        tx.commit();    
        session.close();    //执行close()方法之后,就会由持久对象转换成脱管对象
   
        System.out.println(stu); // 脱管对象


(3)脱管状态:
与持久(Persistent)状态对象关联的Session被关闭后,对象就变为脱管(Detached)的。对脱管(Detached)对象的引用依然有效,对象可继续被修改。脱管(Detached)对象如果重新关联到某个新的Session上,会再次转变为持久(Transistent)的(在脱管Detached其间的改动将被持久化到数据库)。这个功能使得一种编程模型,即中间会给用户思考时间(user think-time)的长时间运行的操作单元(unit of work).
脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象。
脱管对象具有如下特点:
1、 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;
2、 比瞬时对象多了一个数据库记录标识值。
3、 不在于Session相关联。
4、 脱管对象一定是由持久态对象转化而来。
首先是我们的UML图转换:以及解析:




对以上图形的解析:
1、当一个对象被new了以后此对象处于瞬时态(Transient);
2、然后对此对象执行session的save() 或者saveOrUpdate()方法后,此对象被放入session的一级缓存进入持久态.
2、当再对此对象执行evict()/close()/clear()的操作后此对象进入游离态(Detached)
4、游离态(Detached)和瞬时态(Transient)的对象由于没有被session管理会在适当的时机被java的垃圾回收站(garbage)回收.
5、执行session的get()/load()/find()/iternte()等方法从数据库里查询的到的对象,处于持久态(Persistent).  
6、当对数据库中的纪录进行update()/saveOrUpdate()/lock()操作后游离态的对象就过渡到持久态 
7、处于持久态(Persistent)与游离态(Detached)的对象在数据库中都有对应的记录.
8、瞬时态(Transient)与游离态(Detached)的对象都可以被回收可是瞬时态的对象在数据库中没有对应的纪录,而游离态的对象在数据库中有对用的纪录。

对象状态的总结:(如下图所示)



1、操纵持久化对象-save()
(1)Session 的 save() 方法使一个临时对象转变为持久化对象
(2)Session 的 save() 方法完成以下操作:
(3)把 News 对象加入到 Session 缓存中, 使它进入持久化状态
(4)选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID. 在使用代理主键的情况下, setId() 方法为 News 对象设置 OID 使无效的.
(5)计划执行一条 insert 语句,把Customer对象当前的属性值组装到insert语句中
(6)Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当 News 对象处于持久化状态时, 不允许程序随意修改它的 ID
2、 操纵持久化对象-update() 
(1)Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句.




3、操纵持久化对象-saveOrupdate() 
saveOrUpdate: 
  该方法同时包含save和update方法,如果参数是临时对象就用save方
   法,如果是游离对象就用update方法,如果是持久化对象就直接返回。
如果参数是临时对象就用save方法




如果是游离对象就用update方法




如果是持久化对象就直接返回,不执行操作





二、使对象持久化:
Hibernate认为持久化类(persistent class)新实例化的对象是瞬时(Transient)的。我们可以通过将瞬时(Transient)对象与session关联而把它变为持久(Persistent)的。
DomesticCat fritz=new DomesticCat();
fritz.setColor(Color.GINGER);
fritz.setSex(‘M’);
fritz.setName(“Fritz”);
Long generatedId=(Long) sess.save(frize);


如果Cat的持久化标识(identifier)是generated类型的,那么该标识(indentifier)会自动在save()被调用时产生并分配给cat。如果Cat的持久化标识(identifier)是addigned类型的,或是一个复合主键(composite key),那么该标识(identifier)应当在调用save()之前手动赋予给cat。你也可以按照EJB3 early draft中定义的语句,使用persist()替代save()。
(1)persist()使一个临时实例持久化。然而,它不保证立即把标示符值分配给持久性实例,这会发生在冲刷(flush)的时候。Persist()也保证它在事务边界外调用时不会执行insert语句。这对于长期运行的带有扩展会话/持久化上下文的会话是很游泳的。
(2) save()保证返回一个标示符。如果需要运行insert来获取标示符(如“identity”而非“sequence”生成器),这个insert将立即执行,不管你是否在事务内部还是外部。这对于长期运行的带有扩展会话/持久上下文的会话来说会出现问题。
此外,你可以用一个重载版本的save()方法

这篇关于hibernate中有三种状态:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/665698

相关文章

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

SpringCloud之consul服务注册与发现、配置管理、配置持久化方式

《SpringCloud之consul服务注册与发现、配置管理、配置持久化方式》:本文主要介绍SpringCloud之consul服务注册与发现、配置管理、配置持久化方式,具有很好的参考价值,希望... 目录前言一、consul是什么?二、安装运行consul三、使用1、服务发现2、配置管理四、数据持久化总

Java终止正在运行的线程的三种方法

《Java终止正在运行的线程的三种方法》停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作,停止一个线程可以用Thread.stop()方法,但最好不要用它,本文给大家介绍了... 目录前言1. 停止不了的线程2. 判断线程是否停止状态3. 能停止的线程–异常法4. 在沉睡中停止5

Linux配置IP地址的三种实现方式

《Linux配置IP地址的三种实现方式》:本文主要介绍Linux配置IP地址的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录环境RedHat9第一种安装 直接配置网卡文件第二种方式 nmcli(Networkmanager command-line

Linux下修改hostname的三种实现方式

《Linux下修改hostname的三种实现方式》:本文主要介绍Linux下修改hostname的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下修改ho编程stname三种方式方法1:修改配置文件方法2:hFvEWEostnamectl命

Flutter监听当前页面可见与隐藏状态的代码详解

《Flutter监听当前页面可见与隐藏状态的代码详解》文章介绍了如何在Flutter中使用路由观察者来监听应用进入前台或后台状态以及页面的显示和隐藏,并通过代码示例讲解的非常详细,需要的朋友可以参考下... flutter 可以监听 app 进入前台还是后台状态,也可以监听当http://www.cppcn

Java中有什么工具可以进行代码反编译详解

《Java中有什么工具可以进行代码反编译详解》:本文主要介绍Java中有什么工具可以进行代码反编译的相关资,料,包括JD-GUI、CFR、Procyon、Fernflower、Javap、Byte... 目录1.JD-GUI2.CFR3.Procyon Decompiler4.Fernflower5.Jav

MySQL 中的服务器配置和状态详解(MySQL Server Configuration and Status)

《MySQL中的服务器配置和状态详解(MySQLServerConfigurationandStatus)》MySQL服务器配置和状态设置包括服务器选项、系统变量和状态变量三个方面,可以通过... 目录mysql 之服务器配置和状态1 MySQL 架构和性能优化1.1 服务器配置和状态1.1.1 服务器选项

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.