针对昨天同事遇到的hibernate的问题。算是hibernate最基本的东西。具了解,这个问题不少人遇到过,也很常见,却遇到了还常常会懵了。
为了加深印象,知其然,知其因此然。
以后单纯用原始的Hibernate框架作了一些验证,而且打开执行SQL打印输出台的,得出的结论:
前提是在同一事务中间:
一、利用sql语句, session.createSQLQuery(sql).executeUpdate();进行插入,输出台打印出sql插入语句; 再利用sql语句,进行session.createSQLQuery(sql).uniqueResult(); 也会打印SQL查询语句,没有问题,能够查询到数据。
二、利用hibernate封装操做, session.save(entity); 进行插入,输出台并无打印出插入的SQL语句, 再利用 session.get(entity,id);方法作查询 ;也没有打印出SQL查询语句,可是是能够查询到数据的。到执行事务提交语句时,插入的SQL语句被打印出来
三、利用hibernate的session.save(entity); 进行插入,再利用《HQL》语句进行查询,效果同上面第二点。
四、利用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入数据库,这样看起 来也许不太美观,但颇有效。 sql