1、Hibernate对象的生命周期(瞬时状态、持久化状态、游离状态)

1、瞬时状态(Transient):
  使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联;
2、持久化状态(Parsistent):
  如果对象与Session对象关联起来,且该对象对应到数据库记录,则称该对象处于持久化状态。
3、游离状态(Detached)
  Session被关闭或调用了Session的evict或clear方法把它从Session中移除了,则该对象脱离了Session的管理,持久化状态变成游离状态,这表示该对象不在和数据库保持同步,不受hibernate管理。

2、三种状态的比较

Transient:瞬时状态的对象只存在于内存中。
Parsistent:持久状态的对象分别存在于内存、session对象、数据库之中。
Detached:游离状态的对象存在于内存、数据库之中,但不在session对象中。

3、三种状态之间的转换

1、转化路径详解

1)瞬时对象(Transient)

  new 创建 (无->Transient) ,即:对象通过构造方法成为瞬时态;

2)持久对象(Persistent)

  1.1)get/load (无->Persistent),即:对象可以由session的load或get方法直接成为持久态;

    get通过类名和id从数据库读取指定记录,无匹配记录返回null。
    load通过类名和id从数据库读取指定记录,无匹配记录抛ObjectNotException异常。

  1.2)save/saveOrUpdate/persist (Transient->Persistent) ,即:瞬时态对象可以通过save,saveOrUpdate或persist方法成为持久态;

  1.3)update/saveOrUpdate(Detached->Persistent),即:游离态对象则可以通过update,saveOrUpdate成为持久态;

3)游离对象(Detached)

  游离态只能由持久态转换而来(Persistent->Detached),通过close、clear、evict方法实现。

  evict--把某个对象从session中移除,变为游离态;
  clear--把所有对象从session中移除,对象全部变为游离态;
  close--关闭session,其中的对象全部变为游离态;

2、几种方法的详解

1、get 与 load

  都是从数据库中加载数据封装为java对象,直接变为持久态;

2、save,update与saveOrUpdate

  save是将瞬时态转为持久态;
  update是将游离态转为持久态;
  saveOrUpdate可以说是两者的综合,它执行时先判断对象的状态(主要是通过有无主键判断的),若是自由态,则save,若是游离态,则update;

3、save与persist

  两者都是将对象由瞬时态转为持久态,但返回值不同:save返回主键值,而persist不返回;

4、实例,详见注解状态(封装的工具类详见Demo)

  1. package com.demo.test;
  2.  
  3. import org.hibernate.Session;
  4. import org.junit.Test;
  5.  
  6. import com.demo.Utils.HibernateUtil;
  7. import com.demo.pojo.User;
  8.  
  9. public class SessionTest {
  10.  
  11. @Test
  12. public void saveTest() {
  13. Session session = null;
  14. User user = null;
  15. try {
  16. session = HibernateUtil.currentSession();
  17. session.beginTransaction();
  18. //创建瞬时状态对象
  19. user = new User();
  20. user.setName("东方不败");
  21. user.setPwd("123456");
  22. //user仍是一个瞬态对象
  23.  
  24. //持久状态,user被session管理,并且id有值 -- oid
  25. //此时user已变成 持久态对象
  26. session.save(user);
  27.  
  28. //在持久状态下脏数据检查:当提交事务,清理缓存时发现session中的数据与数据库的数据不一致时,会把session的数据更新到数据库
  29. //保存以后,再修改对象,会产生多条sql语句,效率降低,所以在save前修改数据
  30. user.setName("西方求败");
  31. session.getTransaction().commit();
  32. }catch (Exception e) {
  33. e.printStackTrace();
  34. }finally {
  35. HibernateUtil.closeSession();
  36. }
  37. //close、clear、evict方法都会使持久态对象 变成 游离状态 -- user
  38. user.setName("令狐冲");
  39.  
  40. try {
  41. session = HibernateUtil.currentSession();
  42. session.beginTransaction();
  43. //update使对象变成 持久状态
  44. session.update(user);
  45. session.getTransaction().commit();
  46. }catch (Exception e) {
  47. e.printStackTrace();
  48. }finally {
  49. HibernateUtil.closeSession();
  50. }
  51. }
  52.  
  53. @Test
  54. public void getTest() {
  55. Session session = null;
  56. try {
  57. session = HibernateUtil.currentSession();
  58. //get后变为持久状态
  59. //get方法会立即查询该对象:范围(查询不到去下一级查询)从session -> sessionFactory ->数据库
  60. //get方法找不到对象,不会有异常,返回nul
  61. User user = session.get(User.class, 7L);
  62. System.out.println(user.toString());
  63.  
  64. User user2 = session.get(User.class, 17L);
  65. System.out.println(user2);
  66. }catch (Exception e) {
  67. e.printStackTrace();
  68. }finally {
  69. HibernateUtil.closeSession();
  70. }
  71. }
  72.  
  73. @Test
  74. public void loadTest() {
  75. Session session = null;
  76. try {
  77. session = HibernateUtil.currentSession();
  78. //load后变为持久状态(这里加载机制与get不同,稍后我会单独写一篇文章 介绍 get与load 的区别)
  79. //对象不存在时,抛出异常
  80. User user = session.load(User.class, 7L);
  81. System.out.println(user.toString());
  82.  
  83. User user2 = session.load(User.class, 17L);
  84. System.out.println(user2.toString());
  85. }catch (Exception e) {
  86. e.printStackTrace();
  87. }finally {
  88. HibernateUtil.closeSession();
  89. }
  90. }
  91.  
  92. @Test
  93. public void clearTest() {
  94. Session session = null;
  95. User user = null;
  96. try {
  97. session = HibernateUtil.currentSession();
  98. session.beginTransaction();
  99. user = session.get(User.class,7L);
  100. System.out.println(user.getName());
  101. session.getTransaction().commit();
  102. session.clear();
  103. //游离状态,不被session管理,数据库不会被更改
  104. user.setName("任我行");
  105. System.out.println(user.getName());
  106. }catch (Exception e) {
  107. e.printStackTrace();
  108. }finally {
  109. HibernateUtil.closeSession();
  110. }
  111. }
  112.  
  113. @Test
  114. public void updateTest() {
  115. Session session = null;
  116. User user = null;
  117. try {
  118. session = HibernateUtil.currentSession();
  119. session.beginTransaction();
  120. //瞬时状态
  121. //手动构造对象 也可以修改,但是需要指定所有的属性值,否则,不设置的对象会置空,不建议这样update数据
  122. /*user = new User();
  123. user.setId(7L);
  124. user.setName("盈盈");
  125. session.update(user);*/
  126. //一般这样修改
  127. //先去查询
  128. user = session.get(User.class,7L);
  129. if(user != null) {
  130. user.setName("盈盈");
  131. session.update(user);
  132. }
  133. session.getTransaction().commit();
  134. }catch (Exception e) {
  135. e.printStackTrace();
  136. }finally {
  137. HibernateUtil.closeSession();
  138. }
  139. }
  140.  
  141. @Test
  142. public void deleteTest() {
  143. Session session = null;
  144. User user = null;
  145. try {
  146. session = HibernateUtil.currentSession();
  147. session.beginTransaction();
  148. //瞬时状态
  149. //手动构造一个对象,指定主键是可以删除数据的,不建议这样搞
  150. /*user = new User();
  151. user.setId(7L);
  152. session.delete(user);*/
  153. //应该这样删除数据
  154. //从数据先加载该对象,然后删除,可以避免异常
  155. user = session.get(User.class, 7L);
  156. if(user != null) {
  157. session.delete(user);
  158. }
  159. session.getTransaction().commit();
  160. }catch (Exception e) {
  161. e.printStackTrace();
  162. }finally {
  163. HibernateUtil.closeSession();
  164. }
  165. }
  166.  
  167. }

PS:源码地址   https://github.com/JsonShare/hibernate-demo

PS:原文地址  http://www.cnblogs.com/JsonShare/p/8686078.html

Hibernate学习(4)- Hibernate对象的生命周期的更多相关文章

  1. java之hibernate之session中对象的生命周期

    1. session是用来执行对象的crud操作,并且session是对象事务工厂.session是线程级别的,所以生命周期比较短. 2.session中对象的生命周期图: 3.session中对象的 ...

  2. [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. hibernate 持久化对象的生命周期 2.1

    持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...

  4. hibernate 持久化对象的生命周期

    持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...

  5. Hibernate中Java对象的生命周期

    一个对象的出生源于我们的一个new操作,当我们使用new语句创建一个对象,这个对象的生命周期就开始了,当我们不在有任何引用变量引用它,这个对象就的生命就此结束,它占用的内存就可以被JVM的垃圾回收器回 ...

  6. [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. Hibernate学习笔记-Hibernate HQL查询

    Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...

  9. hibernate 学习 五 hibernate核心接口

    一 Configuration接口 Configuration对象只存在于系统的初始化阶段.配置相关. 配置文件可以使用默认的路径,也可以指定路径. Configuration config = ne ...

随机推荐

  1. hihocoder Challenge 29 B.快速乘法

    这题的题解和我写的有一拼,异常简洁,爆炸. 这题思路dp 表示的是讨论到第位,并比原数的前n位多了 显然j只能取0,1,毕竟2进制嘛 之后转移就好了,注意下面两个重要状态 #include <c ...

  2. MySql获取所有表名

    如何获取MySql中所有表的的表名? sql语句是:show tables 返回结果如下: 不仅仅返回了所有的表名,更返回了视图的名字.

  3. 微信小程序—微信自动退款

    微信小程序—微信自动退款 一.业务背景 微信自动退款串接基于酷客多小程序商城系统,为方便财务人员进行订单退款而开发,将酷客多小程序系统财务退款流程和微信退款系统打通.实现一个系统管理运营. 二.业务流 ...

  4. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  5. Jenkins + Github持续集成构建Docker容器,维基百科&人工自能(AI)模块

    本文分两部分,第一部分是手动计划任务的方式构建Github上的Docker程序,第二部分是用Github webhook Trigger一个自动构建任务. Jenkins采用2.5版本Docker采用 ...

  6. 【Luogu4137】Rmq Problem/mex (莫队)

    [Luogu4137]Rmq Problem/mex (莫队) 题面 洛谷 题解 裸的莫队 暴力跳\(ans\)就能\(AC\) 考虑复杂度有保证的做法 每次计算的时候把数字按照大小也分块 每次就枚举 ...

  7. [Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos

    题面 sol 设\(f_{i,j}\)表示填了前\(i\)个字母,在\(AC\)自动机上跑到了节点\(j\)的最大得分.因为匹配需要暴跳\(fail\)所以预先把\(fail\)指针上面的匹配数传下来 ...

  8. [LOJ2230][BJOI2014]大融合

    题面戳我 sol LCT维护子树size. 开一个数组\(sz_i\)表示一个节点的所有虚儿子的size和,\(sum_i\)表示以一个节点为根的子树的\(size\)和,可见\(sz_u=\sum_ ...

  9. [BZOJ1430] 小猴打架 (prufer编码)

    Description 一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友.每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友.经过N-1次打架之后,整个森 ...

  10. RabbitMQ教程C#版 - Hello World

    先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以 ...