首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 2.1 升級至 3.0 完整遷移指南:API、映射、HQL 三大變更詳解

     編輯:Java 相關知識

前言:兼容性與共存策略

Hibernate 3.0 原始碼不兼容 2.1,但設計時充分考慮升級便利性。現有專案可平滑遷移,且 3.0 與 2.1 允許同一應用程式並存運行。

遷移涉及三大面向:

  1. API 變更 → 影響 Java 程式碼
  2. 中繼資料變更 → 影響 O/R 映射檔
  3. HQL 查詢語句變更

一、API 變更詳解

1.1 套件重命名:並存關鍵

  • 根套件:net.sf.hibernate → org.hibernate
  • Criteria API:net.sf.hibernate.expression → org.hibernate.criterion

升級首步:全專案替換 import 陳述式。外部庫(如 EHCache)若引用舊介面,需同步升級或改用 Hibernate 3.0 內建 org.hibernate.cache.EhCacheProvider。

1.2 廢棄 API 集中於 org.hibernate.classic

舊介面移至 org.hibernate.classic,透過子介面相容。SessionFactory.openSession() 回傳 org.hibernate.classic.Session,含 find()、iterate()、delete(String hql)、saveOrUpdateCopy() 等廢棄方法。

完全遷移寫法:

org.hibernate.Session session = sessionFactory.openSession();
// 使用 createQuery() 統一查詢,DELETE 批次刪除,merge() 替代 saveOrUpdateCopy()

快速相容寫法:

org.hibernate.classic.Session session = sessionFactory.openSession();
// 繼續使用舊 API

1.3 批次更新/刪除:3.0 核心增強

2.1 需先載入物件至記憶體,3.0 直接執行 HQL 批次操作:

// 批次更新
String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updated = session.createQuery(hqlUpdate)
    .setString("newName", newName)
    .setString("oldName", oldName)
    .executeUpdate();

// 批次刪除
String hqlDelete = "delete Customer where name = :oldName";
int deleted = session.createQuery(hqlDelete)
    .setString("oldName", oldName)
    .executeUpdate();

1.4 異常模型:RuntimeException 體系

HibernateException 及所有子類別改繼承 RuntimeException,編譯器不再強制檢查,簡化錯誤處理程式碼。

1.5 createSQLQuery() 遷移

移至 org.hibernate.classic.Session,3.0 採用新 SQLQuery 介面實現相同功能。

1.6 Lifecycle/Validatable/Interceptor 變更

  • Lifecycle、Validatable 移至 org.hibernate.classic
  • Interceptor 新增兩方法、instantiate() 參數變更、isUnsaved() 改名 isTransient()
  • 自訂 UserType/CompositeUserType 需實作新增方法,並移至 org.hibernate.usertype
  • 新增 ParameterizedType 介面支援使用者自訂類型重用

1.7 FetchMode/持久化列舉/Blob-Clob 支援

  • FetchMode.LAZY/EAGER 廢棄,改用 SELECT/JOIN
  • PersistentEnum 移除,改用 UserType 處理列舉
  • Blob/Clob 實例自動包裝,支援脫離、序列化、反序列化、merge() 傳遞

1.8 擴展 API 重大變更

org.hibernate.criterion、mapping、persister、collection 結構大幅重構。多數應用不受影響,若擴展相關類別需謹慎升級。

二、中繼資料(映射檔)變更

2.1 檢索策略預設值反轉

  • 2.1:lazy 預設 false
  • 3.0:lazy 預設 true

升級策略:映射檔 <set>、<class> 等元素顯式加 lazy="true",或於 <hibernate-mapping> 設 default-lazy="false" 保持舊行為。

2.2 物件識別符映射簡化

  • unsaved-value 可選,預設 "0"
  • 自然主鍵與脫離物件不再強制實作 Interceptor.isUnsaved(),3.0 自動查詢資料庫判斷狀態(效能稍遜,建議顯式實作)

2.3 集合映射元素重命名

  • <index> 部分情況下由 <list-index> 取代
  • <key-many-to-many> → <map-key-many-to-many>
  • <composite-index> → <composite-map-key>

2.4 DTD 版本更新

<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

三、HQL 查詢語句變更

3.1 雙查詢翻譯器並存

3.0 採 ANTLR 新翻譯器,2.1 經典翻譯器保留。於 hibernate.cfg.xml 選擇:

<!-- 3.0 ANTLR 翻譯器 -->
hibernate.query.factory_class=org.hibernate.hql.ast.ASTQueryTranslatorFactory

<!-- 2.1 經典翻譯器 -->
hibernate.query.factory_class=org.hibernate.hql.classic.ClassicQueryTranslatorFactory

3.2 ANTLR 翻譯器已知 Bug 與對策

不支援某些 theta-style 連結查詢方言(Oracle8i OracleDialect、Sybase11Dialect)。解決方案:

  1. 改用 ANSI-style 方言(如 Oracle9Dialect)
  2. 回退經典翻譯器

3.3 indices()/elements() 函數調整

  • SELECT 子句廢棄兩函數,改用顯式連結查詢
  • WHERE 子句仍可使用 elements()

結語

Hibernate 3.0 帶來批次操作、新翻譯器、改進異常模型等重大增強。遵循本指南逐步遷移:先替換套件名、再調整映射檔、最後驗證 HQL,並善用雙翻譯器並存特性平滑過渡。建議優先遷移核心模組,邊測試邊釋出。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved