<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Junky's IT Notebook

    統計

    留言簿(8)

    積分與排名

    WebSphere Studio

    閱讀排行榜

    評論排行榜

    Hibernate2.1升級到Hibernate3.0 (轉)

    盡管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 = 困惑ldName";
    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 = 困惑ldName";
    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

    對象-關系映射文件中的DTD文檔,由原來的:
    http://hibernate.sourceforge.net/hi...mapping-2.0.dtd
    改為:
    http://hibernate.sourceforge.net/hi...mapping-3.0.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()函數





    hibernate2 升級為hibernate3的需要注意的事

    1.首先將hibernate2.jar替換為hibernate3.jar(hibernate-3.0.5)
    hibernate-tools.jar也替換成新的(從hibernate-tools-3.0.0.alpha4a找出來的)
    2.將所有程序中的net.sf.hibernate替換為org.hibernate.

    3.但是有例外
    net.sf.hibernate.expression.Expression換為org.hibernate.criterion.Expression
    如果用eclipse,用ctrl+shift+o快捷鍵可以加快速度憨笑

    4.在使用hql查詢時將
    createSQLQuery(hql,"c",EZCampaignDTO.class);改為createSQLQuery(hql).addEntity("c",EZCampaignDTO.class);

    5.在批量插入時
    將原來的int size = ((SessionFactoryImpl)(session.getSessionFactory())).getJdbcBatchSize()
    改為int size = ((SessionFactoryImpl)(session.getSessionFactory())).getSettings().getJdbcBatchSize();

    6.在計算count時
    將原來的int size = ((Integer) session.iterate(hql).next()).intValue();
    改為int size = ((Integer) session.createQuery(hql).iterate().next()).intValue();
    其中hql="select count(*) from " + DAOVar.contactClass;

    7.還有就是把.hbm中的hibernate-mapping-2.0.dtd替換為hibernate-mapping-3.0.dtd
    Hibernate Mapping DTD 2.0替換為Hibernate Mapping DTD 3.0

    8.hibernate.cfg.xml中
    Hibernate Mapping DTD 2.0替換為Hibernate Mapping DTD 3.0
    <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>

    9.hibernate.properties中類似

    10.cache-config.xml中
    <provider className="net.sf.hibernate.cache.OSCacheProvider"/>替換為
    <provider className="org.hibernate.cache.OSCacheProvider"/>

    11.classeshibernate.properties中
    hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
    hibernate.dialect=org.hibernate.dialect.SQLServerDialect
    暈s了,怎么這里還有
    還是用編輯器暴力替換一下吧干脆

    然后部署,集成測試,希望一切ok
    結果咣鐺,還是報錯

    12.在自動外部模塊部分有一個功能是根據模版自動生成.hbm文件在load,結果出來的.hbm中有問題:
    生成的 <composite-id unsaved-value="any" mapped="false">其中mapped="false" 出錯.
    找了半天才發現在網上的hibernate-mapping-3.0.dtd文件有支持mapped="false"這個屬性.而本地的hebernate3.0.5中的
    hibernate-mapping-3.0.dtd文件沒有這個屬性.暈,hibernate也太不負責了吧. 解決辦法把hibernate-mapping-3.0.dtd
    copy到jboss\bin目錄下然后,在template文件中
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "hibernate-mapping-3.0.dtd">
    然后他會在jboss\bin目錄下讀取該文件

    13.重新測試,還是咣鐺
    發現子類讀父類數據時拋出異常
    "org.hibernate.LazyInitializationException: could not initialize proxy"
    延遲抓取出的錯,hb3對many-to-one的默認處理是lazy = "proxy"
    沒有搞懂到底怎么回事,把所有many-to-one,one-to-one都加上lazy="false"
    再測試終于大功告成

    posted on 2006-08-28 10:56 junky 閱讀(477) 評論(0)  編輯  收藏 所屬分類: hibernate

    主站蜘蛛池模板: 最新精品亚洲成a人在线观看| 99久久综合精品免费| 在线精品自拍亚洲第一区| 亚洲av日韩专区在线观看| 亚洲欧美日韩一区二区三区在线| 亚洲国产日韩视频观看| 亚洲人成77777在线播放网站不卡 亚洲人成77777在线观看网 | 91亚洲性爱在线视频| 亚洲午夜在线一区| 亚洲熟女综合一区二区三区| 亚洲人成色在线观看| 亚洲精品乱码久久久久久V| 午夜亚洲WWW湿好爽 | 亚洲成在人线av| 亚洲av永久无码精品国产精品| 久久亚洲精品成人综合| 亚洲视频在线观看地址| 亚洲精品综合在线影院| 亚洲av第一网站久章草| 一个人看的免费观看日本视频www| 亚洲免费日韩无码系列| 免费日本一区二区| av无码免费一区二区三区| 欧亚精品一区三区免费| 国产zzjjzzjj视频全免费| 亚洲色偷拍区另类无码专区| 亚洲精品无码mv在线观看网站| 亚洲国产精久久久久久久| 亚洲欧洲视频在线观看| 亚洲国产精华液2020| 人与动性xxxxx免费| 国产成人精品无码免费看| 免费H网站在线观看的| 精品国产精品久久一区免费式| 亚洲а∨天堂久久精品| 亚洲成Av人片乱码色午夜| 亚洲精品中文字幕乱码影院| 亚洲av无码无线在线观看| 国产免费区在线观看十分钟| 少妇太爽了在线观看免费视频| 成人A级毛片免费观看AV网站|