Hibernate 作為 Java 持久層標杆框架,其核心價值在於透明化物件關係映射 (ORM)、提供多層級快取機制、管理實體物件生命週期。本文系統梳理 Hibernate 初始化流程、雙層快取架構、三大物件狀態轉換,助你建立完整心智模型。
啟動過程分四步,核心是建立線程安全、重量級的 SessionFactory:
hibernate.cfg.xml (或 hibernate.properties) 及映射檔 (*.hbm.xml / 註解類),在記憶體構建完整配置元資料模型。Configuration cfg = new Configuration().configure();SessionFactory sf = cfg.buildSessionFactory();Session s = sf.openSession(myConnection);Session s = sf.openSession(); 從配置的連線池 (C3P0/DBCP/Hikari) 取得連線。save(), get(), load(), createQuery() 等。關鍵點:SessionFactory 是單例、不可變、線程安全的重量級物件,應用生命週期只建一次;Session 是輕量級、非線程安全、請求範圍的單位工作。
session.clear() 可手動清空。get/load 同一 ID 返回同一物件實例 (== 比較為 true),實現「同一事務內物件唯一性」。CacheProvider。<class-cache>)、集合級 (<collection-cache>)、查詢級 (Query.setCacheable(true))。read-only (唯讀、最高效)、read-write (讀寫)、nonstrict-read-write (非嚴格讀寫)、transactional (JTA 事務)。存放映射元資料 (實體/屬性/關聯定義)、預編譯 SQL (Named Query、Criteria 編譯結果)、ID 生成器狀態 等,屬於框架基礎設施,非使用者資料快取。
理解狀態機是掌握 Hibernate 行為的關鍵:
| 狀態 | 特徵 | 進入方式 | 離開/轉換 |
|---|---|---|---|
| Transient (臨時/瞬時) | • 不在 Session 快取 • 資料庫無對應記錄 • 無 ID 或 ID 未持久化 |
• new Entity()• session.delete(entity) 後 |
• session.save/persist() → Persistent• 成為垃圾回收 |
| Persistent (持久/托管) | • 在 Session 快取 (L1) • 資料庫有對應記錄 • Session 會在 flush/commit 時自動同步髒資料 |
• save/persist()• get/load()• find/list() 返回• update/saveOrUpdate() (從 Detached) |
• session.close() → Detached• session.evict() → Detached• session.delete() → Transient (資料庫記錄也會刪) |
| Detached (遊離/脫管) | • 不在 Session 快取 • 資料庫可能有記錄 • 有 ID 值 |
• session.close()• session.evict()• session.clear()• 序列化/反序列化 |
• update/saveOrUpdate/merge() → Persistent• 成為垃圾回收 |
new() save/persist() close/evict
Transient ----------------> Persistent ------------------> Detached
^ | ^ |
| | | update/saveOrUpdate/merge
| delete() | | |
+-------------------------+ +-------------------------+
(DB record also deleted) (re-attach to new Session)
load() 拋出 ObjectNotFoundException 時物件仍是 Persistent?load() 可能返回代理,異常拋出時該代理未關聯 Session,屬 Transient/Detached 邊界狀態。evict() 能提升效能?saveOrUpdate() / merge() 處理遊離物件重新關聯;優先用 merge() (JPA 標準),返回新的 Persistent 實例,避免原實例狀態混淆。Hibernate 的精髓在於:SessionFactory 封裝不可變元資料與二級快取,Session 封裝一級快取與資料庫對話,實體物件在三態間流轉。深入理解初始化鏈路、快取層級職責、狀態轉換觸發條件,才能寫出高效、正確、易維護的持久層代碼,並能從容排查 LazyInitializationException、StaleObjectStateException 等經典疑難雜症。