hibernate flush 机制与调用 saveOrupdate 后不立即打印 sql 的问题

今天遇到了一个奇怪的问题,hibernate保存时,不打印sql语句。

为了加深印象,知其然,知其所以然。
 
之后单纯用原始的Hibernate框架做了一些验证,并且打开执行SQL打印输出台的,得出的结论:
 
前提是在同一事务中间:
 
1、利用sql语句, session.createSQLQuery(sql).executeUpdate();进行插入,输出台打印出sql插入语句; 再利用sql语句,进行session.createSQLQuery(sql).uniqueResult(); 也会打印SQL查询语句,没有问题,可以查询到数据。
 
2、利用hibernate封装操作, session.save(entity); 进行插入,输出台并没有打印出插入的SQL语句, 再利用 session.get(entity,id);方法做查询 ;也没有打印出SQL查询语句,但是是可以查询到数据的。到执行事务提交语句时,插入的SQL语句被打印出来
 
3、利用hibernate的session.save(entity); 进行插入,再利用《HQL》语句进行查询,效果同上面第二点。
 
4、利用hibernate的session.save(entity); 进行插入,输出台并没有打印出插入的SQL语句。 再利用sql语句,进行session.createSQLQuery(sql).uniqueResult(); 会打印SQL查询语句。问题出现了,查询不到任何数据。这种情况下利用session.flush()方法,在查询之前执行到flush()方法,输出台 会打印出插入的SQL语句。 再进行查询就有数据。
 
验证完成之后,查了下往上资料,对于第四点,在开发过程中出现频繁,  非常的常见,相信很多人都曾遇到,但又有很多人继续摸不到头脑正好以此加深了印象。
 
从打印控制台SQL可以看出:一个基本的hibernate save方法的操作流程:
 
1. 判断所要保存的实例是否已处于持久化状态,如果不是,则将其置入缓存;
 
2. 根据所要保存的实例计划一条insert sql语句,注意只是计划,并不执行;
 
3. 事务提交时执行之前所计划的insert语句;
 
将tx.commit()换成session.flush,此时控制太打印出了insert语句,但是数据库中并没有添加新的记录;
 
flush方法的主要作用就是清理缓存,强制数据库与Hibernate缓存同步,以保证数据的一致性。它 的主要动作就是向数据库发送一系列的sql语句,并执行这些sql语句,但是不会向数据库提交。而commit方法则会首先调用flush方法,然后提交 事务。这就是为什么我们仅仅调用flush的时候记录并未插入到数据库中的原因,因为只有提交了事务,对数据库所做的更新才会被保存下来。因为 commit方法隐式的调用了flush,所以一般我们都不会显示的调用flush方法。

这是hibernate的flush机制。在一些复杂的对象更新和保存的过程中就要考虑数据库操作顺序的改变以及延时flush是否对程序的结果有 影响。如果确实存在着影响,那就可以在需要保持这种操作顺序的位置加入flush强制Hibernate将缓存中记录的操作flush入数据库,这样看起 来也许不太美观,但很有效。


             转自:     点击打开链接
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值