Session.flush和session.evict方法一起使用出现的问题

Flush:清空临时存储区Insertion,把缓存中的existsInDataBase=true,然后发出sql语句

Evict:清空缓存的EntiryEntires 中数据,但是不清空临时存储区Insertion的数据

Uuid生成策略下,在save以后,在Habernate的临时存储区Insertion和缓存中都会有数据,但是都没有提交到数据库existsInDataBase=false,这个时候如果调用evict,就会把缓存EntiryEntires 中的数据全部清除,但是却不会清除临时存储区中的内容。这个时候当执行commit的时候,session在临时存储区中发现了数据就会执行sql。然后会去缓存中更新缓存中的数据,把existsInDataBase=true.但是这个时候缓存中的数据已经被evict清除了。找不到existsInDataBase。这个时候Habernate会报线程安全异常。

这是因为在Session在清理缓存时,会去临时存储区Insertion取出数据进行insert操作后,需要更新EntiryEntires 中的existsInDataBase属性为TRUE,如果找不到这个属性,就会报异常,而我们的evict会把所有信息从EntiryEntires 清除了。所以找不到相关数据就抛异常

例如使用如下代码

//因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理

//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false

session.save(user);

//将user对象从session中逐出,即session的EntityEntries属性中逐出

session.evict(user);

//无法成功提交,因为hibernate在清理缓存时,在session的insertions集合中取出user对象进行insert操作后需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将user从session的entityEntries中逐出了,所以找不到相关数据,无法更新,抛出异常

tx.commit();

解决上面问题的办法就是再执行save以后马上执行flush,这个flush会发出sql,同时将临时存储区Insertion清空。再执行evict会把EntiryEntires 中的数据清除。然后就执行commit的时候缓存中已经完全空了。所以不会有异常

实际代码如下

//因为user的主键生成策略采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理

//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false

session.save(user);

//flush后hibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user对象

//清除,并且设置session中existsInDatebase的状态为true

session.flush();

//将user对象从session中逐出,即session的EntityEntries属性中逐出

session.evict(user);

//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象

//所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态

tx.commit();

Native生成策略下的evict

这个策略下,当执行save的时候就会把临时存储区Insertion清空,然后发出sql,然后把缓存的EntiryEntires的existsInDataBase属性为TRUE。

然后如果调用evict,又会把EntiryEntires中的数据清空,然后commit的时候不会执行任何信息,也没有异常,这种异常只在uuid生成策略下出现。

实际代码如下:

//因为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();

Hibernate执行insert,update,delete的顺序

在一个session线程中,如果存在多个insert,update,delete操作。Habernate会先把insert批量操作,然后是update,然后是delete。而不是按照我们代码的编写顺序进行执行。在某些情况下,这个特点会引起一些错误。

解决这个问题的办法就是在写好一个insert或者update以后,马上显示执行flush,马上执行这个save发出sql。就可以处理这个问题

就象下面这样

session = HibernateUtils.getSession();

tx = session.beginTransaction();

User3 user = new User3();

user.setId("003");

user.setName("张三");

session.save(user);

user.setName("王五");

session.update(user);

//注意这里,在sava和update以后执行flush

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();

Session.flush和session.evict相关推荐

  1. don't flush the Session after an exception occurs 异常原因

    使用了SSH框架,保存订单是出现了null id in entry (don't flush the Session after an exception occurs异常,很是郁闷,自己排查了插入的 ...

  2. don't flush the Session after an exception occurs异常

    最近在用hibernate的时候遇到了这个异常,去了一些论坛看了看,一些博主为了赚人气不公布答案,这苦了一群小鸟们,今天我同样遇到这个异常,并且我也解决了,不知道大家报错的地方是不是一样? 我的源码: ...

  3. session传递参数_分布式 Session 之 Spring Session 架构与设计

    作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 ​前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...

  4. Session分布式共享 = Session + Redis + Nginx

    一.Session 1.Session 介绍 我相信,搞Web开发的对Session一定再熟悉不过了,所以我就简单的介绍一下. Session:在计算机中,尤其是在网络应用中,称为"会话控制 ...

  5. php session 域,PHP session 跨子域问题总结

    今天,做项目时候遇到个问题.之前做东西的时候session一般就直接存在数据库中这样就能解决跨域 不仅仅是跨子域,但是今天遇到这个问题是,自己要在别人现有的东西上面做修改.由于仅仅是子域 当时就行肯定 ...

  6. session、flask session知识的相关收集

    1.打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的ses ...

  7. 利用spring session解决共享Session问题

    https://blog.csdn.net/patrickyoung6625/article/details/45694157 1.共享Session问题 HttpSession是通过Servlet容 ...

  8. Spring Session - Cookie VS Session VS Token 以及 Session不一致问题的N种解决方案

    文章目录 Cookie VS Session VS Token History Cookie Session Token Session不一致问题 Session不一致解决方案 nginx sessi ...

  9. Tomcat的SessionID引起的Session Fixation和Session Hijacking问题

    上一篇说到<Spring MVC防御CSRF.XSS和SQL注入攻击>,今天说说SessionID带来的漏洞攻击问题.首先,什么是Session Fixation攻击和Session Hi ...

最新文章

  1. 查看IIS上面的每个网站分别用了多少内存
  2. linux学习blog
  3. HTML图片瓦片,HTML5 可扩展瓦片式导航栏
  4. Eclipse基金会发布MicroProfile 2.2,适用于Java微服务
  5. 求数组非连续子序列的最大和
  6. hystrix应用 博客_使用Hystrix DSL创建弹性骆驼应用程序
  7. 4-1k近邻算法(k-Nearest Neighbors)
  8. HttpServletRequest说明
  9. B站在港交所挂牌上市 12名UP主共同敲钟
  10. date time 和string
  11. 百会ZOHO发布基于SaaS面向中小企业的CRM平台
  12. lpt监控安装_lpt1(如何在lpt1端口安装打印机)
  13. K3默认序时簿是不体现即时库存的,如果需要在序时簿将物料的即时库存数据带入,可以按照下方的步骤实现:
  14. 微信小程序(沧海一笑)
  15. (附源码)springboot菠萝大学课室预约系统分析与设 毕业设计 641656
  16. 分享:Android清除本地数据缓存代码
  17. 【算法思想】数学归纳法在算法题中的应用(含例题举例)
  18. 测绘专业计算机二级,测绘本科毕业,几年具有考二级注册结构师资格?
  19. 基于ZYNQ的嵌入式学习笔记四(矩阵键盘实现电子琴)
  20. 网易云音乐“王牌冤家”用户评论:评论爬虫及情感分析(SnowNLP)

热门文章

  1. 重磅新品3D打印机“智能微工厂”CP-01引全球关注,本周强势登陆
  2. 文本预处理(收集+预处理)
  3. ASJ系列剩余电流继电器在海洋平台的应用
  4. 安科瑞剩余电流继电器在智能建筑中的应用
  5. VS 2008 头文件库文件设置
  6. 计算思维的结构 | 单元测验1
  7. 文件权限管理 -- u+s、g+s、o+t/三种用户权限
  8. Design and verification of diffractive optical elements for speckle generation of 3-D range sensors
  9. 《J2SE 回炉再造07》-------溺水狗
  10. 如何生成随机数+原理详细分析