EJB3.0是Hibernate的克隆嗎
摘要 Sun的EJB 3.0規范正處于其最后的"沖刺"階段,許多公司都在為遵循這一規范而忙碌著。這個EJB規范最新版本所提供的眾多優點中比較突出的當屬其數據庫功能,但是一些開發人員感到,這個規范僅僅是Hibernate持久性存儲引擎的一個"克隆"版。真的嗎?本文正是想討論這一問題。
實踐證明,Hibernate是針對于Java語言所創建的最優秀的持久化存儲引擎之一。至今,我還清晰地記得第一次使用Hibernate工作的情景。當時,我們已經有了一種現成的持久化存儲引擎,但是這個引擎將消耗大量的系統資源并且從未真正正確工作過。令人驚奇的是,Hibernate"瞬間"解決了我們的持久化存儲問題!這真是一個"天賜之物"。不覺間,時間快速推進到今天。EJB 3.0又浮出水面,并且不久我們就要計劃把我們當前的EJB 2.x服務器向這個更高版本升級了。然而,仔細地分析一下EJB 3.0中所作的持久性存儲變化,有人可能會感到驚訝-這不是來自于Hibernate的一個"克隆"品嗎?難道Sun當真"偷竊"了來自于Hibernate的設計嗎?我的回答是,情況要比這些復雜得多。
一、 EJB 3.0
EJB 3.0必須實現的重要目標之一是,要使之成為更為有用和更易于使用的開發工具。Sun公司的Linda DeMichiel認識到,為了成功實現這一目標,EJB 3.0必須要基于開發人員今天正在使用的現有庫;否則,它將會導致一種困難的升級操作并且可能會引不起足夠的重視。因此,來自于Oracle,JBoss,Apache,BEA,Novell,Google的成員和其它方面的專家都被邀請參與制訂這一規范。這個小組的目標是,生產一種規范-能夠使得EJB更易于開發并且還要創建一種便于開發人員能夠容易地實現升級的持久性存儲標準。
當這個小組開始開發EJB 3.0規范時,他們很快認識到,其中很多特征應該在功能上與所有的主要的供應商和庫保持一致。我們將在下面的幾節中討論這些特征。
(一) EntityManager
這個EntityManager負責處理一個事務。在JDO中,它被稱作持久性存儲管理器,而在Hibernate中稱它為一個會話。在GlassFish工程中,EntityManager被作如下描述:
其實,一個EntityManager實例與一個持久性存儲上下文相關聯。一個持久性存儲上下文是一組實體實例,其中的任何一個持久性實體都是唯一的一個實體實例。在該持久性存儲上下文中,實體實例及其生命周期都是可被管理的。這個接口定義了用于與持久性存儲上下文進行交互的方法。EntityManager API用于創建和刪除持久性實體實例-通過其主鍵查找實體和查詢實體。
這個可由一個給定的EntityManager實例管理的實體集合是通過一個持久性存儲單元進行定義的。一個持久性存儲單元定義了所有類的集合,這些類是相聯系的或由應用程序加以分組,并且它們必須共存于它們到單個數據庫的映射中。
(二) 命名查詢
一個命名查詢是一個預定義的查詢,它被賦予一個名字,這樣它可以在以后通過該名字加以存取。用數據庫術語來說,命名查詢被稱作存儲過程。當結合本機查詢時(見下一節),數據庫查詢應該是非常輕松的。
(三) 本機查詢
不是使用具有很多限制性的實體查詢語言,本機查詢允許直接從EJB中全面地使用SQL語言。現在,我們有可能直接在數據庫上調用count(),max()和其它功能而不必付出其它周折。
(四) 回調監聽器
回調監聽器,是一種事件監聽器,或用數據庫術語來說是,是一種觸發器。它們支持當一個事件發生時進行代碼調用。
(五) 脫離/重新依附對象
能夠脫離開一個EntityManager的控制范圍而又能夠重新返回而被持續化存儲,這在EJB 3.0版本之前是無法實現的。在以前,為了實現這一目的,必須把來自于一個對象的值必須被復制到一個POJO(普通Java對象)中,然后被再往回復制。
在EJB 3.0之前,我總是使用值-對象并且把來自于EJB的值復制到一個POJO中;然后,使用在前端使用該對象。如果該POJO中的一個值被改變,它將不得不被"推回"到該EJB;然后,該值被復制回來。這種"混亂"狀態現在已經不復存在了。一個對象甚至能夠完全離開JVM并且在以后某個時期返回回來并且被重新依附。這種改變所帶來的效率是不能被低估的。
(六) O/R映射類型
能夠把一個EJB中的字段直接映射到一個數據庫中的列上是EJB 3.0以前也是很難實現的。這一功能實現一直不那么令人滿意,并且很多第三方開發工具都一再推遲對這種功能的支持。我最喜歡的xDoclet的一個特征是,它能夠定義在我的EJB中每一個持久性字段對應哪種SQL類型。借助于EJB 3.0和注解技術,我們不再需要使用一種第三方工具。
二、 EJB 3.0對象
值得注意的是,企業Java Bean現在被稱為POJO。隨著注解技術的出現,java bean不再需要接口、home和描述符支持文件。僅僅這個特征就為EJB 3.0贏得了大批開發團隊的青睞。
現在,既然企業對象不再被鎖定到應用程序服務器內,那么我們不再需要把它們復制進和復制出POJO,這樣就允許不必把應用程序服務器后端和前端區別得那么嚴格,從而使開發人員能夠更容易地顯示和編輯存儲于EJB中的數據。我們很快就會看到這些變化對xDoclet所產生的有趣影響。
三、 結論
盡管毫無疑問,EJB 3.0基于Hibernate,但是,事實上它是基于所有的頂級的對象/關系映射工具。看來,這個工具并非這些工具簡單"修改"版,而事實上是由Sun創造的又一部杰出的"電影"。不必讓開發人員學習一種"全新的但還是功能相同的工具",開發人員只需要輕松地花一些時間就可以升級到新版的EJB 3.0中,因為EJB 3.0正是基于他們已經了解和喜歡的工具創建的。
實踐證明,Hibernate是針對于Java語言所創建的最優秀的持久化存儲引擎之一。至今,我還清晰地記得第一次使用Hibernate工作的情景。當時,我們已經有了一種現成的持久化存儲引擎,但是這個引擎將消耗大量的系統資源并且從未真正正確工作過。令人驚奇的是,Hibernate"瞬間"解決了我們的持久化存儲問題!這真是一個"天賜之物"。不覺間,時間快速推進到今天。EJB 3.0又浮出水面,并且不久我們就要計劃把我們當前的EJB 2.x服務器向這個更高版本升級了。然而,仔細地分析一下EJB 3.0中所作的持久性存儲變化,有人可能會感到驚訝-這不是來自于Hibernate的一個"克隆"品嗎?難道Sun當真"偷竊"了來自于Hibernate的設計嗎?我的回答是,情況要比這些復雜得多。
一、 EJB 3.0
EJB 3.0必須實現的重要目標之一是,要使之成為更為有用和更易于使用的開發工具。Sun公司的Linda DeMichiel認識到,為了成功實現這一目標,EJB 3.0必須要基于開發人員今天正在使用的現有庫;否則,它將會導致一種困難的升級操作并且可能會引不起足夠的重視。因此,來自于Oracle,JBoss,Apache,BEA,Novell,Google的成員和其它方面的專家都被邀請參與制訂這一規范。這個小組的目標是,生產一種規范-能夠使得EJB更易于開發并且還要創建一種便于開發人員能夠容易地實現升級的持久性存儲標準。
當這個小組開始開發EJB 3.0規范時,他們很快認識到,其中很多特征應該在功能上與所有的主要的供應商和庫保持一致。我們將在下面的幾節中討論這些特征。
(一) EntityManager
這個EntityManager負責處理一個事務。在JDO中,它被稱作持久性存儲管理器,而在Hibernate中稱它為一個會話。在GlassFish工程中,EntityManager被作如下描述:
其實,一個EntityManager實例與一個持久性存儲上下文相關聯。一個持久性存儲上下文是一組實體實例,其中的任何一個持久性實體都是唯一的一個實體實例。在該持久性存儲上下文中,實體實例及其生命周期都是可被管理的。這個接口定義了用于與持久性存儲上下文進行交互的方法。EntityManager API用于創建和刪除持久性實體實例-通過其主鍵查找實體和查詢實體。
這個可由一個給定的EntityManager實例管理的實體集合是通過一個持久性存儲單元進行定義的。一個持久性存儲單元定義了所有類的集合,這些類是相聯系的或由應用程序加以分組,并且它們必須共存于它們到單個數據庫的映射中。
(二) 命名查詢
一個命名查詢是一個預定義的查詢,它被賦予一個名字,這樣它可以在以后通過該名字加以存取。用數據庫術語來說,命名查詢被稱作存儲過程。當結合本機查詢時(見下一節),數據庫查詢應該是非常輕松的。
(三) 本機查詢
不是使用具有很多限制性的實體查詢語言,本機查詢允許直接從EJB中全面地使用SQL語言。現在,我們有可能直接在數據庫上調用count(),max()和其它功能而不必付出其它周折。
(四) 回調監聽器
回調監聽器,是一種事件監聽器,或用數據庫術語來說是,是一種觸發器。它們支持當一個事件發生時進行代碼調用。
(五) 脫離/重新依附對象
能夠脫離開一個EntityManager的控制范圍而又能夠重新返回而被持續化存儲,這在EJB 3.0版本之前是無法實現的。在以前,為了實現這一目的,必須把來自于一個對象的值必須被復制到一個POJO(普通Java對象)中,然后被再往回復制。
在EJB 3.0之前,我總是使用值-對象并且把來自于EJB的值復制到一個POJO中;然后,使用在前端使用該對象。如果該POJO中的一個值被改變,它將不得不被"推回"到該EJB;然后,該值被復制回來。這種"混亂"狀態現在已經不復存在了。一個對象甚至能夠完全離開JVM并且在以后某個時期返回回來并且被重新依附。這種改變所帶來的效率是不能被低估的。
(六) O/R映射類型
能夠把一個EJB中的字段直接映射到一個數據庫中的列上是EJB 3.0以前也是很難實現的。這一功能實現一直不那么令人滿意,并且很多第三方開發工具都一再推遲對這種功能的支持。我最喜歡的xDoclet的一個特征是,它能夠定義在我的EJB中每一個持久性字段對應哪種SQL類型。借助于EJB 3.0和注解技術,我們不再需要使用一種第三方工具。
二、 EJB 3.0對象
值得注意的是,企業Java Bean現在被稱為POJO。隨著注解技術的出現,java bean不再需要接口、home和描述符支持文件。僅僅這個特征就為EJB 3.0贏得了大批開發團隊的青睞。
現在,既然企業對象不再被鎖定到應用程序服務器內,那么我們不再需要把它們復制進和復制出POJO,這樣就允許不必把應用程序服務器后端和前端區別得那么嚴格,從而使開發人員能夠更容易地顯示和編輯存儲于EJB中的數據。我們很快就會看到這些變化對xDoclet所產生的有趣影響。
三、 結論
盡管毫無疑問,EJB 3.0基于Hibernate,但是,事實上它是基于所有的頂級的對象/關系映射工具。看來,這個工具并非這些工具簡單"修改"版,而事實上是由Sun創造的又一部杰出的"電影"。不必讓開發人員學習一種"全新的但還是功能相同的工具",開發人員只需要輕松地花一些時間就可以升級到新版的EJB 3.0中,因為EJB 3.0正是基于他們已經了解和喜歡的工具創建的。