針對昨天同事遇到的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