@[TOC]Hibernate学习笔记Session.evict(user)方法

Hibernate学习笔记Session.evict(user)方法

首先我们要明白Session.flush(user)方法,这个方法主要做了三件事:

  1. 根据session缓存中的临时集合insertion中的state区中的数据(user对象),发送sql语句。
  2. 清空临时集合中的数据。
  3. 向session中的缓存map中的existsInDatebase状态设置为为true,表示数据库中已经有了这个数据。

接着来看session.evict(user);这句话表示将user对象从Session缓存中逐出,即从Session中的EntityEntries属性中逐出。这句话的作用就是清理session缓存,以防数据量过多,造成缓存的崩溃。

接着来看下面代码:

第一个例子:/*** 测试uuid主键生成策略*/public void testSave1() {Session session = null;Transaction tx = null;try {session = HibernateUtils.getSession();//通过session工厂获取session对象tx = session.beginTransaction();//开启事务User1 user = new User1();user.setName("李四");user.setPassword("123");user.setCreateTime(new Date());user.setExpireTime(new Date());session.save(user);//这里设置user的主键为userId,主键生成策略为uuid,所以调用完成save后,只是将user纳入到了session的管理,//不会发出insert语句,但是id已经生成,session(缓存)中existsInDatebase状态为false(数据库中并不存在)session.flush();//调用flush,hibernate会清理缓存,1,根据临时集合执行sql//如果数据库的隔离级别设置为为提交读,那么我们可以看到flush过的数据//2,清空临时集合中的数据//3,并且session中existsInDatebase状态为true(表示数据库中已经存在)//提交事务//默认情况下commit操作会先执行flush清理缓存,所以不用显示的调用flush//commit后数据是无法回滚的tx.commit();}catch(Exception e) {e.printStackTrace();tx.rollback();}finally {HibernateUtils.closeSession(session);}}

在native主键生成策略中,由于主键生成策略是uuid,所以在save的时候并不会发送sql语句进行保存,所以这个时候,如果使用session.evict(user);清理缓存中的user对象,那么无法成功commit,因为hiberbate清理完临时集合之后,需要将existsInDatebase状态为true,这个时候由于evict已经将user对象从session缓存中逐出,所以hibernate找不到相关数据,所以提交失败。

/*** 测试uuid主键生成策略中的session.evict(user)。*/public void testSave3() {Session session = null;Transaction tx = null;try {session = HibernateUtils.getSession();tx = session.beginTransaction();User1 user = new User1();user.setName("王五");user.setPassword("123");user.setCreateTime(new Date());user.setExpireTime(new Date());//因为user的主键生成策略采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为falsesession.save(user);//将user对象从session(缓存)中逐出,即session的EntityEntries属性中逐出session.evict(user);//目的是清除map中的缓存中的user对象。//无法成功提交,因为hibernate在清理缓存时,在session的临时insertions集合中取出user对象进行insert操作后//需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将user从session的entityEntries//中逐出了,所以找不到相关数据,无法更新,抛出异常   tx.commit();}catch(Exception e) {e.printStackTrace();tx.rollback();}finally {HibernateUtils.closeSession(session);}}

解决方法:在session.exict(user);语句之前使用session.flush();,这样子hibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user对象清除,并且设置session中existsInDatebase的状态为true,那么在commit的时候,会根据session缓存中insertion中的state中的数据发送sql语句,由于之前已经将user对象从缓存中逐出,所以这个时候找不到user对象,于是就不会发送sql语句也不会更新existsInDatebase的状态,也不会出异常了。
看代码:

/*** 测试uuid主键生成策略*/public void testSave4() {Session session = null;Transaction tx = null;try {session = HibernateUtils.getSession();tx = session.beginTransaction();User1 user = new User1();user.setName("王五");user.setPassword("123");user.setCreateTime(new Date());user.setExpireTime(new Date());//因为user的主键生成策略采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为falsesession.save(user);//flush后hibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user对象//清除,并且设置session中existsInDatebase的状态为truesession.flush();//将user对象从session中逐出,即session的EntityEntries属性中逐出session.evict(user);//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象//所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态tx.commit();}catch(Exception e) {e.printStackTrace();tx.rollback();}finally {HibernateUtils.closeSession(session);}}

使用native主键生成策略,毫无疑问,不用在session.evict之前显示调用flush方法,也是行的通的。因为他在save的时候就已经发送了sql语句了,然后commit的时候,找不到user对象之后,不会发送sql也是无所谓的了,因为之前已经发送过了。
看代码:

/*** 测试native主键生成策略*/public void testSave5() {Session session = null;Transaction tx = null;try {session = HibernateUtils.getSession();tx = session.beginTransaction();User2 user = new User2();user.setName("张三11");user.setPassword("123");user.setCreateTime(new Date());user.setExpireTime(new Date());//因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id//纳入了session的管理,修改了session中existsInDatebase状态为true//如果数据库的隔离级别设置为非提交读,那么我们可以看到save过的数据session.save(user);//将user对象从session中逐出,即session的EntityEntries属性中逐出session.evict(user);//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象//所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态tx.commit();}catch(Exception e) {e.printStackTrace();tx.rollback();}finally {HibernateUtils.closeSession(session);}}

主键生成策略为designed的时候,分析思略和之前的一样,
看代码:

/*** 测试assigned主键生成策略* */public void testSave7() {Session session = null;Transaction tx = null;try {session = HibernateUtils.getSession();tx = session.beginTransaction();User3 user = new User3();user.setId("003");user.setName("张三");session.save(user);user.setName("王五");session.update(user);session.flush();User3 user3 = new User3();user3.setId("004");user3.setName("李四");session.save(user3);//Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)//Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?//Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)//因为我们在session.udpate(user)后执行了flush,所以在清理缓存时执行flush前的sql不会生成//sql会按照我们的意愿执行tx.commit();}catch(Exception e) {e.printStackTrace();tx.rollback();}finally {HibernateUtils.closeSession(session);}}

我们的对手不是天才,而是脚踏实地的人。

Hibernate学习笔记Session.evict(user)方法相关推荐

  1. hibernate学习笔记(总结)

    hibernate学习笔记 课程内容 6 1 HelloWorld 6 2 Hibernate原理模拟-什么是O/R Mapping以及为什么要有O/R Mapping 6 3 常见的0/R框架(了解 ...

  2. 马士兵Hibernate学习笔记

    马士兵hibernate学习笔记 课程内容 6课程内容 1 HelloWorld 6 2 Hibernate原理模拟-什么是O/R Mapping以及为什么要有O/R Mapping 6 3 常见的0 ...

  3. hibernate学习笔记二

    上一篇关于hibernate学习笔记一,主要是作为hibernate的入门知识.没有和spring发生任何关系,这一篇我将把spring集成进去,看spring如何管理hibernate,还有和未使用 ...

  4. 《Go语言圣经》学习笔记 第六章 方法

    <Go语言圣经>学习笔记 第六章 方法 目录 方法声明 基于指针对象的方法 通过嵌入结构体来扩展类型 方法值和方法表达式 示例:Bit数组 封装 注:学习<Go语言圣经>笔记, ...

  5. Ui学习笔记---EasyUI的使用方法,EasyLoader组件使用

    Ui学习笔记---EasyUI的使用方法,EasyLoader组件使用 技术qq交流群:CreDream:251572072 1.使用之前导入文件:   这里用jquery-easyui-1.2.6 ...

  6. js学习笔记2 -- js使用方法

    js学习笔记2 -- js使用方法 方法一,使用外部js文件(推荐使用) 方法二,写在script标签中 方法三,写到标签的onclick属性中 方法四,使用超链接 方法一,使用外部js文件(推荐使用 ...

  7. wyy课堂cmos模拟设计课学习笔记-gm/Id设计方法介绍及曲线仿真

    wyy课堂cmos模拟设计课学习笔记-gm/Id设计方法及曲线仿真 总思路 需要的图像曲线 软件操作 举例说明 总思路 这在b站上也有教学视频:https://www.bilibili.com/vid ...

  8. 凸优化学习笔记 15:梯度方法

    前面的章节基本上讲完了凸优化相关的理论部分,在对偶原理以及 KKT 条件那里我们已经体会到了理论之美!接下来我们就要进入求解算法的部分,这也是需要浓墨重彩的一部分,毕竟我们学习凸优化就是为了解决实际当 ...

  9. Hibernate学习笔记二:Session

    Session概述 Session是Hibernate提供的最主要的接口,它提供了基本的保存, 更新, 删除和加载 Java 对象的方法. Session 具有一个缓存, 位于缓存中的对象称为持久化对 ...

最新文章

  1. Python学习笔记:循环语句
  2. Numpy中求向量和矩阵的范数
  3. 我国最新十大黑科技发布,颠覆你的想象!
  4. 前端学习:Vue.js基本使用
  5. iOS蓝牙BLE4.0通信功能
  6. 基于jquery的tab切换
  7. CAD数据与ArcGIS数据的互转换
  8. js 判断支持webgl_「WebGL基础」:第一部分
  9. 【YOLO家族】【论文翻译】YOLO 9000 /YOLO V2
  10. UDP与TCP报文格式,字段意义
  11. 计算机实验室安全知识心得体会,实验室安全知识宣传
  12. 使用HEVC官方编码器HM
  13. panabit连接控制
  14. 关卡 动画 蓝图 运行_虚幻4 UE4 蓝图之关卡蓝图实现自动开关门
  15. Xcode6内置环境变量(Build Setting Macros)
  16. CSDN博客如何更换皮肤
  17. ubuntu企业微信解决无法查看、发送图片
  18. 夫妻贷款买房需要注意什么
  19. [算法]发散思维能力题目
  20. 零知识证明:Sigma协议

热门文章

  1. MWC2018 大会5G成大热门 中国芯大有可为
  2. 431金融带计算机,金融硕士考研:考研金融431能带计算器吗?
  3. jQuery(4)——jQuery hide、show方法的简单了解
  4. 鸿蒙应用开发 | 选项卡(TabList / Tab)的功能和用法
  5. 模型5.4——斯皮尔曼spearman相关系数
  6. php 中 实例化对象的 赋值及 指针引用
  7. 捷联惯导系统学习6.6(Sage-Husa自适应滤波 )
  8. 如何提高网页的效率(下篇)——Use YSlow to know why your web Slow
  9. MATLAB中积分命令【计算无穷限积分(广义积分)的函数】
  10. Linux arm系统支持U盘exfat和ntfs