EJB 3.0簡介

javaprogramers發表於2006-05-13

SUN中國軟體技術中心 王強 wynne.wang@sun.com

1 簡化開發的目標

1.1我們的目標

EJB3.0是當前很多人談論的話題,企業軟體開發的一個關鍵是,提供一個儘量簡單的的應用框架:它可以使開發人員不用關注於複雜的侍猓熱縭攣翊懟踩統志沒取?梢約芯刈⒂諫桃德嘸揮黴匭哪切┑筒愕募際蹕附冢傭岣嚦⒄叩男剩玫礁咧柿康娜砑U庖彩侵貧‥JB 3.0規範的目標,簡化開發!


1.2 當前的問題


EJB3.0希望開發人員能夠從這種新的開發模式中受益,更好地推進J2EE的應用. 隨著JAVA不斷的進步和發展,越來越多的企業選擇J2EE作為它們的解決方案,J2EE體系結構提供一個簡化的中間層整合框架來滿足應用的需求。然而,對於一般的開發人員,目前J2EE 1.4下的EJB 2.1 框架有些過於複雜了。 按照EJB2.1規範的定義,EJB元件必須事先很多的介面, 比如Home介面、Remote介面、local 介面,等等.還要針對各種應用型別定義許多的xml描述檔案。當我們需要訪問某個元件或者服務的時候,必須通過JDNI查詢,通過名字繫結服務,才能找到我們需要的物件。

比如我們要使用某個EJB shopping cart, 就要首先實現一個initial context,然後通過他查詢這個EJB 的home 介面,然後呼叫home街口的create方法,得到一個EJB object, 最後呼叫這個EJB object的商務方法. 下面是一個例子:
// EJB 2.1 Client view of the ShoppingCart Bean
...
Context initialContext = new InitialContext();
ShoppingCartHome myCartHome = (ShoppingCartHome)
initialContext.lookup(“JAVA:comp/env/ejb/cart”);
ShoppingCart myCart= myCartHome.create();
//Use the Bean
Collection widgets = myCart.startToShop(Widgets )
...
// Don't forget code to handle JAVAx.ejb.CreateException
...
EJB2.1的規範還要求我們必須實現Javax.EJB裡面定義的介面, 實現裡面的Methods比如 EJBCreate(), EJBPassivate(), and EJBActivate()。大多數情況下這些方法是不需要開發人員作任何修改的。這些規定實際上都和真正核心的商務邏輯沒什麼關係,都只是一些技術模板,規定了開發人員必須按照這樣的模板進行開發. 比如下面這段程式碼:

人們開始思考,怎麼樣才能把EJB的開發變的更加簡單,更好的利用這種技術. 當前正在制定的EJB 3.0的標準的目標就是簡化開發, 讓更多的開發人員被它的易用和強大功能所吸引過來,喜愛這項技術。為了達到這個目標,要做的第一件事情,也是最重要的事情,就是從一個開發人員的角度,將EJB的使用盡量的簡化。

1.3 JCP專家組的工作


這個工作是由EJB3.0 專家組來完成的。我們知道JAVA的開發和推動是由一個開放的組織來完成的,這個組織的名字叫做JAVA Community Process。簡稱JCP. SUN的理念是: 創新無處不在. 所以JCP小組從世界的每個角落聽取關於JAVA的建議,將各方面對JAVA的要求通過制定JSR(JAVA Specification Request )形式確定下來. EJB 3.0規範的JSR編號是 220. 整個專家組的制定成員包括J2EE 註冊使用者, 應用伺服器的開發廠商和J2EE社群的成員.


簡化一個現有的技術,尤其是得到廣泛的開發人支援的技術,比如EJB, 不是一個簡單的工作. 作為鋪墊,專家組進行了大量的準備工作,檢驗了EJB技術的複雜性,當前EJB流域流行的各種模式和反模式,以及從客戶和開發人員來的各種需求。開發人員和使用者根據實際的需要,希望EJB能夠提供他們滿意的特性.
檢驗結果發現,大多數情況下,人們不需要更高階的技術,而是需要更簡化的技術,來簡化當前的開發模式。而不是像以前的EJB釋出一樣,在技術複雜度上的提高。定義一個新技術,不僅對老的技術有一定的更新, 也要能充分並容老的技術, 提供一定的向後相容性. 因為採用這些技術的企業,已經在這些技術上投資了很多. 如果因為技術的更新就使得對應的IT系統和資料變得不能使用,是一件非常糟糕的事情.


所以,定義了EJB3.0規範的同時,如何支援現有的EJB技術是非常必要的. 要保證現有的EJB API是持續可用的, 還要和新的EJB3.0 API結合起來, 對早期的API應該繼續提供支援而不是標記為不贊成使用

1.4 標註的新功能


EJB3.0的很多新特性是通過JAVA SE5.0來實現的。這裡我們就要談到JAVA SE 5.0,它所提供的許多特性,其中最有趣的一點就是標註(Annotation)的功能。我們知道以前的JAVA語言都是命令格式的, 比如a.b(), 表示讓類a做事情b, 但是很多時候我們只是需要對某個物件做一些註解,比如對某個類標記為可持續化的Serializable. 這只是一個標記,為了以後的處理提供說明,本身不需要做任何操作。
在Deploy 的時候, 提供了很多說明的XML檔案,比如部署描述檔案,裡面說明了引用的EJB的名字,介面, 以及當前EJB的Transaction Type等等資訊. 所有這些資訊都是說明性的,而不是命令性的. 用來對某個物件的某個屬性坐一段說明. 因此,有一個非常有趣的想法,能不能通過對JAVA語言的擴充套件,結合標註和命令這兩者的優點 ?


這也是有一個專家組在JCP的組織內完成的, JSR規範的編號是JSR 175, 為JAVA SE 5.0支援註解(Annotation)的功能. 這個規範為EJB3.0 的簡化實現提供了一些基本的支援, 也是最關鍵的支援. 標註可以有自己的屬性,也可以定義自己的持續時間,表示這段資訊是否儲存到 原始碼中,還是一直持續到Class中,或者一直保持到執行時間. 標註有自己的預設值.大多數情況下,無須說明我們就可以推算出來這個物件的行為。 
2 輕鬆的實現開發

2.1 減輕開發人員的負擔

EJB3.0的簡化工作包括下面幾個部分:
? 提供一個簡化的API, 包括對EJB的定義,對EJB的引用等等
? 減少開發的類數目,不再需要那麼多的interface
? 相關性注入
? 簡化的查詢機制
? 從開發人員的角度不必要使用部署描述檔案, 很多的工作可以放到程式碼裡面用標註來說明,比如Entity Bean 的Transaction Type
? 簡化的持久化功能
? 簡化和改善資料物件的O/R Mapping.


標註可以應用到程式語言的一些基本元素上,比如類,方法,變數,包等等. 當我們在程式碼中使用了這些標註, 根據這個標註對應的持續策略, 它可以被編譯到Class 檔案中去,或者一直保持到執行的時候。大多數在 EJB 3.0 中定義的標註都是Runtime保持策略, 這樣做的好處是提供了最大的靈活性。而且由於大量工作放到了執行的時候來做,也減少一部分Deploy的工作。


我們通過定義預設的語法來說明大多數常見的情況。開發人員不需要再專門說明常見的情況,“OK, 沒問題,預設的設定就已經可以滿足需要了“ 這樣,開發人員的工作大大減輕了。
這也引出來了EJB3.0中的一個很有意思的概念 "Configuration By Exception" --只有在例外的情況下才需要我們的參與.


EJB3.0的目標是簡化開發人員的工作,讓他們專注於商務應用的開發而不是把精力放到很多繁瑣的例行工作上,這些工作可以交給Container來完成。EJB通過注入來指定自己需要的資源,不用再寫那些麻煩的方法. 將物件的建立和獲取提取到外部。由外部容器提供需要的元件。這樣,開發人員只用在開始的時候定義,說我需要這個資源, 後面就可以直接使用這個資源, 這樣會大大的簡化開發, 因為開發人員只用關心如何使用這個物件和商務方法, 而不用擔心其他的技術細節。

2.2 拋開繁瑣的細節
下面我們看看都作了那些簡化。我們的目的是把那些繁瑣的技術細節隱藏起來,程式開發人員只用關心自己的商務邏輯程式碼,而不用關心那些複雜的技術模板,必須實現的介面等,哪怕這些方法和介面根本不需要實現.

? 不再需要EJB的部件介面
? 每個EJB 都只是一個普通的JAVA Class
? 不再需要home介面, 我們不再用home 來建立這個EJB
? 不再需要實現javax.ejb.EnterpriseBean藉口
? 對於需要在回撥方法裡實現的部分,我們採用標註的方式說明一個方法為回撥方法
? 不再需要使用複雜的JNDI名字呼叫機制,對於需要服務或者資源的地方
? 我們採用了相關性注入的方法,另外也可以通過簡化的lookup方法來查詢資源

下面讓我們看一個簡單的無狀態SessionBean的例子。無狀態session Bean是最簡單也是最常用 Bean,很多初學EJB的人都從無狀態Session Bean開始。如何讓無狀態Session Bean 變的簡單易用成為一個非常有意義的話題。

前面假設我們已經定義了相關的interface, 這個EJB2.1的的功能是對員工的工資做處理,開啟一個資料庫連線,進行員工工資資訊的某些操作,等等.

// EJB 2.1
public Class PayrollBean implements JAVAx.ejb.SessionBean
{
SessionContext ctx;
DataSource empDB;
public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
public void ejbCreate() {
Context initialContext = new InitialContext();
empDB = (DataSource)initialContext.lookup( JAVA:comp/env/jdbc/empDB );
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
public void setBenefitsDeduction (int empId, double deduction) {
...
Connection conn = empDB.getConnection();
...
}
...
}
// NOTE deployment descriptor needed


這裡我們首先要實現一個 sessionBean interface,保持一個對sessioncontext的引用,然後是在EJBcreate 方法裡面我們呼叫JNDI得到一個datasource。 後面我們必須要定義一些回撥方法,雖然這些方法我們不會實現任何邏輯。然後在 商務方法裡面,我們開啟一個資料庫連線。

注意,我們還沒有完。為了使用這個EJB, 必須加上xml的部署描述檔案打好包。

下面是一個常見的部署描述檔案可以是這樣子的。

<session>
<ejb-name>PayrollBean</ejb-name>
<local-home>PayrollHome</local-home>
<local>Payroll</local>
<ejb-class>com.example.PayrollBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>jdbc/empDB</res-ref-name>
<res-ref-type>javax.sql.DataSource</res-ref-type>
<res-auth>Container</res-auth>
</resource-ref>
</session>
...
<assembly-descriptor>
...
</assembly-descriptor>

從開發人員的角度來檢查這樣一個簡單的EJB 是非常有意義的。我們可以更好的理解有那些地方可以有改動。一個主要的問題是,定義了這麼多的方法和結構以後,程式的清晰化受到了影響,結構變得混亂。真正需要關注的商務方法沒有很好的強調和體現。

下面讓我們看一看EJB 3.0 是如何實現一個簡單的stateless session Bean的。

// Same example, EJB 3.0
@Stateless public class PayrollBean implements Payroll {
@Resource DataSource empDB;
public void setBenefitsDeduction (int empId, double deduction) {
...
Connection conn = empDB.getConnection();
...
}
...
}


@Stateless 標註表示這是一個stateless session Bean. 使用這樣的標註可以讓我們不再需要使用SessionBean 介面, 這樣就大大的簡化了EJB的實現類。 Bean的商務介面是payroll. 這是一個普通的JAVA interface. 預設的情況,container會把他作成一個local interface. 如果需要實現一個遠端介面,只需再定義一個標註 @Remote. 注意在介面裡面不需要定義 RemoteExceptions,它由Container 層在後面處理掉了

2.3 引用物件的新方法
在老的EJB規範中,還有一個比較複雜的地方是訪問環境物件。EJB 2.1 裡面訪問環境要首先在元件定義的相關性引用,比如resource-refs, EJB-refs, 然後在JNDI名字空間裡面配置這些環境物件。 最後查詢執行的時候JNDI空間裡面查詢這些環境物件
EJB 3.0對此提供了兩種簡化的方案:

1) 相關性注入
2) 一個簡化的查詢lookup方法

相關性注入是一種技術,開發人員在原始碼中加入標註的一個定義,說明需要這個環境物件,然後由Container在初始化的時候把真的環境物件注入裡面。
目前EJB3.0 spec裡面有兩種注入方式,setter注入和變數注入, 這些在以後的規範中可能會有變化,比如一種統一的注入方式。 我們可以通過注入標記@EJB來定義一個EJB的引用,也可以通過注入標記@resource 表示我們要引用一個資源,它可以是EJB以外的一切環境物件. 專家組為了儘可能的簡化開發,將使用注入的物件型別作了簡化。

EJB3.0 將仍然提供一個動態查詢的方法,但是從程式開發人員的角度,不需要再使用JNDI API,而是採用更為簡化的EJB Context 的 Lookup方法。

在新的EJB 3.0規範中,因為不再需要複雜的home介面和EJB 介面。EJB client端的編碼也大大的簡化了,和訪問一個普通的JAVA 物件沒有什麼區別。上面的那個EJB2.1的例子比較起來,在EJB 3.0 裡面使用一個EJB變的非常簡單,只需要兩行程式碼:

// EJB 3.0 client view
@EJB ShoppingCart myCart;
...
Collection widgets = myCart.startToShop(Widgets );
...

首先定義一個EJB的應用,然後就可以直接呼叫這個EJB的商務方法,剩下的工作由Container來為我們完成。

2.4 新的事務管理

EJB中的事務(Transaction)管理大大簡化了使用者開發程式。把應用分成一個一個小的單元,叫做transaction. 事務系統保證了這個單元裡面的任務是完整的,要麼全部執行,要麼出錯後完全退回到初始狀態。


J2EE中有兩種型別的事務, 容器管理的和Bean管理的。他們在如何啟動和結束事務上是不同的。Bean 管理的事務由元件使用 UserTransaction類顯式啟動和結束的。程式碼中需要呼叫方法 UserTransaction.begin() 和 UserTransaction.commit() 。Container 管理的事物是由container 自動來完成的。
針對不同的事務型別,可以定義6種不同的事務屬性。
事務屬性告訴 Container 是否把EJB方法裡面的工作放到使用者的事務裡面。還是針對這個方法重新啟動一個新的事務. 或者執行這個方法而不包含在事務裡面,等等。
在EJB3.0規範中,我們預設的定義是容器管理的事務. 而且針對所有的Bean方法,應用Required Transaction屬性,它的意思是如果呼叫這個方法的應用沒有Transaction Environment,那麼這個方法會自動建立一個新的。
開發人員可以使用標註的方式在針對整個EJB或者某個具體的方法指定他的Transaction Attribute.
首先我們看一個工資處理的EJB的例子, 這是一個標準的EJB 3.0 Stateless Session Bean。預設情況下,每個方法是都是由container來管理Transaction的,預設的事務屬性是required
// Uses container-managed transction, REQUIRED attribute
@Stateless public PayrollBean implements Payroll {
public void setBenefitsDeduction(int empId, double deduction) {...}
public double getBenefitsDeduction(int empId) {...}
public double getSalary(int empId) {...}
public void setSalary(int empId, double salary) {...}
}

下面還是這個例子,我們知道對於有關重要資料的改動,總是非常敏感的。比如我們在更改某個使用者的工資的時候同時修改他的所得稅,我們希望這兩個呼叫是在同一個Transaction裡面發生的。

@Stateless public PayrollBean implements Payroll {
@TransactionAttribute(MANDATORY)
public void setBenefitsDeduction(int empId, double deduction) {...}
public double getBenefitsDeduction(int empId) {...}
public double getSalary(int empid) {...}
@TransactionAttribute(MANDATORY)
public void setSalary(int empId, double salary) {...}
}

那麼呼叫使用者的工資改動的方法就必須在一個已經存在的Transaction Environment
中,為此,我們用@transactionattribute(mandatory)標註 這個方法必須在一個客戶端的transaction中,如果客戶端沒有這樣的一個 Transaction Context, Container會扔出來一個 Javax.ejb.EjbTransactionRequiredException 的錯誤資訊。

 

2.5 新的安全機制
EJB架構不鼓勵開發人員用程式碼的方式實現安全機制,而是採用安全形色的方法,通過定義可以訪問的安全形色,來限制對某個方法的訪問許可權。

預設情況,在3.0裡面所有的方法都是"unchecked"。也就是說預設情況下對所有方法是不用安全控制策略的。如果呼叫某個方法的客戶端具有某個使用者角色(Role) ,我們可以制定是否這個方法也是沿用這個角色。預設情況下的安全策略是"Caller Identity",也就是說被呼叫者的角色和呼叫者的角色應該是一致的

這是一個EJB 3.0的安全實現的例子。我們對於其他的方法都沒有設定安全策略。但是對於設定某個員工的工資是多少,這樣的安全要求比較高的方法設定了只有人事部門的管理員才能呼叫。我們採用了一個

@RolesAllowed("HR_PayrollAdministrator ")
// Security view
@Stateless public PayrollBean implements Payroll {
public void setBenefitsDeduction(int empId, double deduction) {...}
public double getBenefitsDeduction(int empId) {...}
public double getSalary(int empid) {...}
// salary setting is intended to be more restricted
@RolesAllowed( HR_PayrollAdministrator )
public void setSalary(int empId, double salary) {...}
}

2.6 事件的通知和檢查

EJB 3.0中, 開發人員不需要實現那些不必要的callback methods。 他可以把任意方法指定為一個事件通知方法。通過標記一個通知標註,我們把一個方法標記為一個回撥方法, 例如:

@Stateful public class AccountManagementBean
implements AccountManagement {
Socket cs;
@PostConstruct
@PostActivate
public void initRemoteConnectionToAccountSystem {
...
}

@PreDestroy
@PrePassivate
public void closeRemoteConnectionToAccountSystem {
...
}
...
}

在這個EJB 3.0 的例子當中, 我們定義了一個有狀態的session Bean,把初始化的工作都交給init remote connection方法,同時標記他為一個回撥方法,在construct ,和 activite之後呼叫
同時我們把清理的工作都交給close remote connection方法,同時標記他為一個回撥方法,在destroy 和passivate之前呼叫

對於那些高階的使用者,需要定製自己的事件檢查和偵聽機制。檢查方法和所被檢查的物件方法可以在同一個 Bean 中,也可以在不同的JAVA Class裡面。 這種檢查機制有下面的特點:
? 在方法周圍進行檢查
? 包裝商務方法的整個呼叫過程
? 可以對方法呼叫的引數和結果進行處理
? 檢查類的序列中,可以拿到上下文資料
? 多個檢查類可以按照指定的順序執行
? 可以用部署表述符來指定執行順序

我們用 @Interceptors 標註指定一個外部的檢查方法類, 用 @AroundInvoke制定內部的某個方法為檢查方法。在檢查方法裡面,我們用proceed()來呼叫具體的商務方法。目前的檢查方法是檢查一個Bean裡面的所有方法,專家組正在制定標準, 讓它可以具體到檢查制定的某個方法。

下面是一個EJB3.0的檢查方法的例子:

我們制定了這個無狀態session Bean檢查方法類是這三個類.
accountaudit, metrics, customsecurity。那麼實際執行的時候會按照這個制定的順序來實行
檢查.

@Interceptors({
com.acme.AccountAudit.class,
com.acme.Metrics.class,
com.acme.CustomSecurity.class
})
@Stateless
public class AccountManagementBean
implements AccountManagement {
public void createAccount(int accountId, Details details) {...}
public void deleteAccount(int accountId) {...}
public void activateAccount(int accountId) {...}
public void deactivateAccount(int accountId) {...}
...
}

2.7 部署描述檔案的優先順序

在EJB3.0中,我們可以用標註的方法來指定對環境物件的引用,也可以用部署描述符檔案(Deployment Description)的方式來制定對環境物件的應用, 也可以兩個同時使用. 如果我們在部署描述檔案和程式碼標註中都制定了環境物件,那麼部署描述檔案中的那個引用有更高的優先順序, 這樣就給了應用的Deployer相對比較大的靈活性來控制.

3 持久化的魔力


3.1 最初的目標

EJB 3.0 專家組的另外一個目標是為實體Bean( Entity Bean ) 和物件/關係的對映,提供一個輕量級的模型。實際上,目前關於實體Bean的爭論很多, 很多批評人士對它的架構感到不滿,我們的目標是改善EJB 容器管理的持久化模型,從各地的一些優秀的開源軟體中吸取靈感,從一些反模式(Anti-Pattern)中吸取經驗, 從而讓新的標準稱為技術上的領跑者。 EJB3.0的持續化包括下面的一些特性:

? 簡化實體bean的程式設計方式,減少不必要的開發介面
? 改善EJB的持久化, 為O/R對映提供繼承和多型的資訊
? 可以在EJB Container之外使用實體Bean
? 不需要Container 就可以對商務方法進行測試
? 不再需要資料傳輸物件DTO (Data Transfer Objects) 之類的設計模式(Design Pattern)
? 改善的EJB QL

為了解決這些意見,ejb 3.0 的專家組集中在一個經過簡化的持久化模型,目前業界已經有類似的產品和模式,比如Hibernate和Toplink, 這是一個全新的方向,代表著輕量級的物件/關係(O/R)對映模型。


在EJB3.0中,實體Bean是普通的Java 類, 這是一些真正的類, 而不是抽象類。而且更為簡化的是,開發人員不再需要實現任何介面,不論是商務藉口或者是回撥介面。
而且不再需要實現資料傳輸物件(DTO), 因為現在的Entity Bean本身就是一個簡單的普通JAVA 物件POJO (Plain Old Java Object), 標記為序列化之後就可以在客戶端和服務端進行傳遞,不再需要特殊的處理。

3.2 管理類的角色
在新的EJB3.0規範裡面,我們看到了一個 EntityManager 類, 對於實體Bean而言,這是一個類似於呼叫工廠(Factory)或者統一的Home介面之類的角色。Entity manager自己的生命週期可以由Container或者應用程式都可以來管理。
Entity Manager 將負責跟蹤資料庫事務上下文中, 實體bean 物件的狀態。對於開發人員來說, javax.persistence.EntityManager 成為對實體bean的統一訪問點。 可以把它看作是對實體Bean操作的一個”home”. 我們要通過entity manager 呼叫實體bean的生命週期管理。 比如:Persist, Remove, Merge, Flush, Refresh, 等方法。

Entity Manager是所有Entity Bean的持久化管理介面,任何對Entity Bean的操作都必須通過它來進行。有的開發人員會對這個介面感到熟悉,因為它與Hibernate的Session介面和JDO的Persistence Manager非常相似。Entity Manager的介面主要方法如下:

package javax.ejb;

public interface EntityManager {
public void create(Object entity);
public < T > T merge(T entity);
public void remove(Object entity);
public Object find(String entityName, Object primaryKey);
public < T > T find(Class < T > entityClass, Object primaryKey);
public void flush();
public Query createQuery(String ejbqlString);
public Query createNamedQuery(String name);
public Query createNativeQuery(String sqlString);
public void refresh(Object entity);
public void evict(Object entity);
public boolean contains(Object entity);
}

EntityManager 還大大方便了查詢方法的實現,記得我們在EJB2.1裡面是怎麼做的嗎?在EJB 3.0裡面,可以直接呼叫EntityManager.find(String entityName, Object primaryKey),查詢具有某個主鍵的實體 bean 例項。例如:

public OrderBean findByPrimaryKey(String orderId)
{ return (OrderBean)em.find("OrderBean" , orderId);
}

EntityManager作為Query物件的生產工廠, 可以用createQuery(String ejbQlString) 建立一個EJB QL 查詢,也可以用createNamedQuery(String queryName)來建立一個 NamedQuery 查詢。下面是一個例子:


public List findWithAddr(String addr) {
return em.createQuery(
"SELECT o FROM Orders o WHERE o.addr LIKE :orderAddress")
.setParameter("orderAddress", addr)
.setMaxResults(100)
.listResults();
}

3.3 O/R Mapping的標註


O/R Mappings 標註的後設資料,使得使用者可以修飾他們的EJB3.0 Entity Bean. 在 EJB 3.0預設環境下,表的名字就是類的名字, 兩者是一致的, public Java Bean getter方法假定為訪問表中同樣名字的屬性值, 開發人員可以通過@Table, @column等各種不同的標註來修改這個預設的定義. 例子:


@Entity
@Table(name="CUSTOMER")
@SecondaryTable(name="CUST_DETAIL",
pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID"))
public class Customer { ... }


@Entity 說明這是一個Entity Bean, Table標記了對應的O/R Mapping的主表, 而 SecondaryTable標記了 Entity對應的輔助表,
持續化的API, 和查詢語言,以及O/R Mapping標註, 都是EJB 3.0規範的一部分。
持久化API的設計目標是能夠獨立於Container的執行,只需要有一個Java SE環境就可以執行了。

4 小結


本文以描述了EJB 3.0規範的一些新特性。EJB 3.0將是EJB歷史上最大的一次改動,它充分吸收了一些開源專案,比如Spring、Hibernate的經驗,變得更加方便實用,體現了簡化開發的設計目標。這篇文章希望能夠給大家帶來一點關於EJB 3.0的印象,目前EJB 3.0規範已經進入了Proposed Final Draft階段,當然,將來這個規範的技術細節還可能發生變化。

相關文章