如何把Hibernate2.1升級到Hibernate3.0?

選自<<精通Hibernate:Java對象持久化技術詳解>> 做者:孫衛琴 來源:[url]www.javathinker.org[/url]
 
1.1 Hibernate API 變化
1.1.1 包名
1.1.2 org.hibernate.classic包
1.1.3 Hibernate所依賴的第三方軟件包
1.1.4 異常模型
1.1.5 Session接口
1.1.6 createSQLQuery()
1.1.7 Lifecycle 和 Validatable 接口
1.1.8 Interceptor接口
1.1.9 UserType和CompositeUserType接口
1.1.10 FetchMode類
1.1.11 PersistentEnum類
1.1.12 對Blob 和Clob的支持
1.1.13 Hibernate中供擴展的API的變化
1.2 元數據的變化
1.2.1 檢索策略
1.2.2 對象標識符的映射
1.2.3 集合映射
1.2.4 DTD
1.3 查詢語句的變化
1.3.1 indices()和elements()函數

儘管Hibernate 3.0 與Hibernate2.1的源代碼是不兼容的,可是當Hibernate開發小組在設計Hibernate3.0時,爲簡化升級Hibernate版本做了周到的考慮。對於現有的基於Hibernate2.1的Java項目,能夠很方便的把它升級到Hibernate3.0。
本文描述了Hibernate3.0版本的新變化,Hibernate3.0版本的變化包括三個方面:
(1)API的變化,它將影響到Java程序代碼。
(2)元數據,它將影響到對象-關係映射文件。
(3)HQL查詢語句。
值得注意的是, Hibernate3.0並不會徹底取代Hibernate2.1。在同一個應用程序中,容許Hibernate3.0和Hibernate2.1並存。
1.1 Hibernate API 變化
1.1.1 包名
Hibernate3.0的包的根路徑爲: 「org.hibernate」 ,而在Hibernate2.1中爲「net.sf.hibernate」。這一命名變化使得Hibernate2.1和Hibernate3.0可以同時在同一個應用程序中運行。
若是但願把已有的應用升級到Hibernate3.0,那麼升級的第一步是把Java源程序中的全部「net.sf.hibernate」替換爲「org.hibernate」。
Hibernate2.1中的「net.sf.hibernate.expression」包被更名爲 「org.hibernate.criterion」。假如應用程序使用了Criteria API,那麼在升級的過程當中,必須把Java源程序中的全部「net.sf.hibernate.expression」替換爲 「org.hibernate.criterion」。
若是應用使用了除Hibernate之外的其餘外部軟件,而這個外部軟件又引用了Hibernate的接口,那麼在升級時必須十分當心。例如 EHCache擁有本身的CacheProvider: net.sf.ehcache.hibernate.Provider,在這個類中引用了Hibernate2.1中的接口,在升級應用時,能夠採用如下辦法之一來升級EHCache:
(1)手工修改net.sf.ehcache.hibernate.Provider類,使它引用Hibernate3.0中的接口。
(2)等到EHCache軟件自己升級爲使用Hibernate3.0後,使用新的EHCache軟件。
(3)使用Hibernate3.0中內置的CacheProvider:org.hibernate.cache.EhCacheProvider。
1.1.2 org.hibernate.classic包
Hibernate3.0把一些被廢棄的接口都轉移到org.hibernate.classic中。
1.1.3 Hibernate所依賴的第三方軟件包
在Hibernate3.0的軟件包的lib目錄下的README.txt文件中,描述了Hibernate3.0所依賴的第三方軟件包的變化。
1.1.4 異常模型
在Hibernate3.0中,HibernateException異常以及它的全部子類都繼承了java.lang.RuntimeException。所以在編譯時,編譯器不會再檢查HibernateException。
1.1.5 Session接口
在Hibernate3.0中,原來Hibernate2.1的Session接口中的有些基本方法也被廢棄,但爲了簡化升級,這些方法依然是可用的,能夠經過org.hibernate.classic.Session子接口來訪問它們,例如:

org.hibernate.classic.Session session=sessionFactory.openSession();
session.delete("delete from Customer ");

在Hibernate3.0中,org.hibernate.classic.Session接口繼承了 org.hibernate.Session接口,在org.hibernate.classic.Session接口中包含了一系列被廢棄的方法,如 find()、interate()等。SessionFactory接口的openSession()方法返回 org.hibernate.classic.Session類型的實例。若是但願在程序中徹底使用Hibernate3.0,能夠採用如下方式建立 Session實例:
org.hibernate.Session session=sessionFactory.openSession();
若是是對已有的程序進行簡單的升級,而且但願仍然調用Hibernate2.1中Session的一些接口,能夠採用如下方式建立Session實例:
org.hibernate.classic.Session session=sessionFactory.openSession();
在Hibernate3.0中,Session接口中被廢棄的方法包括:
* 執行查詢的方法:find()、iterate()、filter()和delete(String hqlSelectQuery)
* saveOrUpdateCopy()
Hibernate3.0一概採用createQuery()方法來執行全部的查詢語句,採用DELETE 查詢語句來執行批量刪除,採用merge()方法來替代 saveOrUpdateCopy()方法。

提示:在Hibernate2.1中,Session的delete()方法有幾種重載形式,其中參數爲HQL查詢語句的delete() 方法在Hibernate3.0中被廢棄,而參數爲Ojbect類型的的delete()方法依然被支持。delete(Object o)方法用於刪除參數指定的對象,該方法支持級聯刪除。
Hibernate2.1沒有對批量更新和批量刪除提供很好的支持,參見<<精通Hibernate>>一書的第13章的 13.1.1節(批量更新和批量刪除),而Hibernate3.0對批量更新和批量刪除提供了支持,可以直接執行批量更新或批量刪除語句,無需把被更新或刪除的對象先加載到內存中。如下是經過Hibernate3.0執行批量更新的程序代碼:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
如下是經過Hibernate3.0執行批量刪除的程序代碼:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.createQuery( hqlDelete )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
1.1.6 createSQLQuery()
在Hibernate3.0中,Session接口的createSQLQuery()方法被廢棄,被移到org.hibernate.classic.Session接口中。Hibernate3.0採用新的SQLQuery接口來完成相同的功能。
1.1.7 Lifecycle 和 Validatable 接口
Lifecycle和Validatable 接口被廢棄,而且被移到org.hibernate.classic包中。
1.1.8 Interceptor接口
在Interceptor 接口中加入了兩個新的方法。用戶建立的Interceptor實現類在升級的過程當中,須要爲這兩個新方法提供方法體爲空的實現。此外,instantiate()方法的參數做了修改,isUnsaved()方法被更名爲isTransient()。
1.1.9 UserType和CompositeUserType接口
在UserType和CompositeUserType接口中都加入了一些新的方法,這兩個接口被移到org.hibernate.usertype包中,用戶定義的UserType和CompositeUserType實現類必須實現這些新方法。
Hibernate3.0提供了ParameterizedType接口,用於更好的重用用戶自定義的類型。
1.1.10 FetchMode類
FetchMode.LAZY 和 FetchMode.EAGER被廢棄。取而代之的分別爲FetchMode.SELECT 和FetchMode.JOIN。
1.1.11 PersistentEnum類
PersistentEnum被廢棄並刪除。已經存在的應用應該採用UserType來處理枚舉類型。
1.1.12 對Blob 和Clob的支持
Hibernate對Blob和Clob實例進行了包裝,使得那些擁有Blob或Clob類型的屬性的類的實例能夠被遊離、序列化或反序列化,以及傳遞到merge()方法中。
1.1.13 Hibernate中供擴展的API的變化
org.hibernate.criterion、 org.hibernate.mapping、 org.hibernate.persister和org.hibernate.collection 包的結構和實現發生了重大的變化。多數基於Hibernate
2.1 的應用不依賴於這些包,所以不會被影響。若是你的應用擴展了這些包中的類,那麼必須很是當心的對受影響的程序代碼進行升級。
1.2 元數據的變化
1.2.1 檢索策略
在Hibernate2.1中,lazy屬性的默認值爲「false」,而在Hibernate3.0中,lazy屬性的默認值爲「true」。在升級映射文件時,若是原來的映射文件中的有關元素,如<set>、<class>等沒有顯式設置lazy屬性,那麼必須把它們都顯式的設置爲lazy=「true」。若是以爲這種升級方式很麻煩,能夠採起另外一簡單的升級方式:在<hibernate-mapping> 元素中設置: default-lazy=「false」。
1.2.2 對象標識符的映射
unsaved-value屬性是可選的,在多數狀況下,Hibernate3.0將把unsaved-value="0" 做爲默認值。
在Hibernate3.0中,當使用天然主鍵和遊離對象時,再也不強迫實現Interceptor.isUnsaved()方法。若是沒有設置這個方法,當Hibernate3.0沒法區分對象的狀態時,會查詢數據庫,來判斷這個對象究竟是臨時對象,仍是遊離對象。不過,顯式的使用 Interceptor.isUnsaved()方法會得到更好的性能,由於這能夠減小Hibernate直接訪問數據庫的次數。
1.2.3 集合映射
<index>元素在某些狀況下被<list-index>和<map-key>元素替代。此外, Hibernate3.0用<map-key-many-to-many> 元素來替代原來的<key-many-to-many>.元素,用<composite-map-key>元素來替代原來的 <composite-index>元素。
1.2.4 DTD
1.3 查詢語句的變化
Hibernate3.0 採用新的基於ANTLR的HQL/SQL查詢翻譯器,不過,Hibernate2.1的查詢翻譯器也依然存在。在Hibernate的配置文件中,hibernate.query.factory_class屬性用來選擇查詢翻譯器。例如:
(1)選擇Hibernate3.0的查詢翻譯器:
hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory
(2)選擇Hibernate2.1的查詢翻譯器
hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory

提示:ANTLR是用純Java語言編寫出來的一個編譯工具,它可生成Java語言或者是C++的詞法和語法分析器,並可產生語法分析樹並對該樹進行遍歷。ANTLR因爲是純Java的,所以能夠安裝在任意平臺上,可是須要JDK的支持。
Hibernate開發小組盡力保證Hibernate3.0的查詢翻譯器可以支持Hibernate2.1的全部查詢語句。不過,對於許多已經存在的應用,在升級過程當中,也不妨仍然使用Hibernate2.1的查詢翻譯器。
值得注意的是, Hibernate3.0的查詢翻譯器存在一個Bug:不支持某些theta-style連結查詢方言:如Oracle8i的OracleDialect 方言、Sybase11Dialect。解決這一問題的辦法有兩種:(1)改成使用支持ANSI-style連結查詢的方言,如 Oracle9Dialect,(2)若是升級的時候遇到這一問題,那麼仍是改成使用Hibernate2.1的查詢翻譯器。
1.3.1 indices()和elements()函數
在HQL的select子句中廢棄了indices()和elements()函數,由於這兩個函數的語法很讓用戶費解,能夠用顯式的鏈接查詢語句來替代 select elements(...) 。而在HQL的where子句中,仍然可使用elements()函數。
相關文章
相關標籤/搜索