學習EJB3.0

1.爲了存取那些服務對象,你需要通過服務器的JNDI 來查
找存根對象(session bean)或消息隊列(MDB)。JNDI查找是把客戶端與實際的服務端實現解藕的關鍵步驟。但
是,直接使用一個字符串來進行JNDI查找並不優雅。有這樣幾個原因:
·客戶端與服務端必須有一致的基於字符串的名字。它沒有在編譯時得到認證或在部署時得到檢查。
·從JNDI返回的服務對象的類型沒有在編譯時進行檢查,有可能在運行時出現轉換(casting)錯誤。
·冗長的查找代碼,有着自己的try-catch代碼塊,在應用之間是重複的和雜亂的
EJB 3.0,對任何POJO,提供了一個簡單的和優雅的方法來解藕服務對象和資源。使用@EJB註釋,你可以將EJB
存根對象注入到任何EJB 3.0容器管理的POJO 中。如果註釋用在一個屬性變量上,容器將會在它被第一次訪問
之前賦值給它。依賴注入只工作在本地命名服務中,因此你不能注入遠程服務器的對象。

2.消息驅動Bean(MDB)是設計用來專門處理基於消息請求的組件。一個MDB類必須實現MessageListener 接口。當
容器檢測到bean守候的隊列一條消息時,就調用onMessage()方法,將消息作爲參數傳入。MDB在OnMessage()
中決定如何處理該消息。你可以用註釋來配置MDB 監聽哪一條隊列。當MDB 部署時,容器將會用到其中的注
釋信息。
當一個業務執行的時間很長,而執行結果無需實時向用戶反饋時,很適合使用消息驅動Bean。如訂單成功後給用
戶發送一封電子郵件或發送一條短信等。下面的例子在用戶下訂單完成後,打印一份配送單。好讓配送員根據地
址把商品送到客人手中。

3. 小提示:如果你的表已經存在,並且想保留數據,發佈實體bean時可以把hibernate.hbm2ddl.auto的值設爲none或
update,以後爲了實體bean 的改動能反應到數據表,建議使用update,這樣實體Bean添加一個屬性時能同時在數
據表增加相應字段。

4. 實體Bean 發佈前的準備工作
(1) 配置數據源並放置在[jboss 安裝目錄]/server/all/deploy 目錄,把數據庫驅動Jar 包放置在[Jboss 安裝目
錄]/server/all/lib 目錄下,放置後需要重啓Jboss服務器。如果數據源已經存在就不需要配置。
(2) 配置persistence.xml文件,在文件中指定使用的源據源及各項參數。
(3) 把實體類和persistence.xml文件打成Jar,persistence.xml 放在jar 文件的META-INF目錄。

5. EntityManager 是由EJB容器自動地管理和配置的,不需要用戶
自己創建,他用作操作實體Bean。

6. 在類中不用對EntityManager em進行賦值,後面卻可以直接使用他。這是因爲在實體Bean加載
時,容器通過@PersistenceContext註釋動態注入EntityManager 對象。
如果persistence.xml文件中配置了多個不同的持久化內容。你需要指定持久化名稱注入EntityManager 對象,可以
通過@PersistenceContext註釋的unitName屬性進行指定。如果只有一個持久化內容配置,不需要明確指定。

7. 發佈在JBOSS 中的WEB應用調用EJB
有些調用EJB 的WEB 應用是直接發佈在Jboss 集成環境下,本教程的客戶端調用例子就是發佈在Jboss 中。在
Jboss下發布WEB應用,需要把WEB應用打包成war 文件。另外在此環境下調用EJB不需要把EJB的接口類放
入/WEB-INF/classes/目錄中,否則調用Stateful Bean 就會發生類型衝突,引發下面的例外。
java.lang.ClassCastException: $Proxy84
org.apache.jsp.StatefulBeanTest_jsp._jspService(org.apache.jsp.StatefulBeanTest_jsp:55)
注意:在此環境下,EJB的Local或Remote接口都可以被調用。

8. EntityManager 是用來對實體Bean進行操作的輔助類。他可以用來產生/刪除持久化的實體Bean,通過主鍵查找
實體bean,也可以通過EJB3 QL語言查找滿足條件的實體Bean。實體Bean被EntityManager管理時,EntityManager
跟蹤他的狀態改變,在任何決定更新實體Bean的時候便會把發生改變的值同步到數據庫中。當實體Bean從
EntityManager 分離後,他是不受管理的,EntityManager 無法跟蹤他的任何狀態改變。
當在數據庫中沒有找到記錄時,getReference()和find()是有區別的,find()方法會返回null,而getReference()方法
會拋出javax.persistence.EntityNotFoundException例外,另外getReference()方法不保證實體Bean已被初始化。
如果傳遞進getReference()或find()方法的參數不是實體Bean,都會引發IllegalArgumentException例外。

9. 更新Merge()
    通過merge (person)方法可以把Entity Bean更新到數據庫。Entity Bean的狀態有兩種情況。
第一種:Entity Bean仍然受EntityManager 管理。
第二種:Entity Bean已經脫離了EntityManager 的管理。這種情況的出現一般是把實體Bean返回到了客戶端,在客戶端對實體Bean作了修改後把他返回給EJB接口進行更新操作。
    執行updatePerson(person)方法的時候,如果此時容器中已經存在一個受EntityManager 管
理的具有相同ID 的person實例,容器將會把傳進的person參數的內容拷貝進這個受管理的實例。merge()方法會
返回這個受管理的實例,但傳進updatePerson方法的參數person仍然是分離的不受管理的。還有另外一種情況:
如果此時容器中不存在受EntityManager管理的具有相同ID的person實例,容器將會根據傳進的person參數Copy
出一個受EntityManager 管理的person實例,通過這個受管理的實例進行數據庫更新操作,同時merge()方法會返
回出這個受管理的實例。傳進updatePerson方法的參數person仍然是分離的不受管理的。
如果傳遞進merge ()方法的參數不是實體Bean,會引發一個IllegalArgumentException例外。

10. 刷新實體refresh()
    如果你懷疑當前被管理的實體已經不是數據庫中最新的數據,你可以通過refresh()方法刷新實體,容器會把數據
庫中的新值重寫進實體。這種情況一般發生在你獲取了實體之後,有人更新了數據庫中的記錄,這時你需要得到
最新的數據。當然你再次調用find()或getReference()方法也可以得到最新數據,但這種做法並不優雅。

11.@ManyToOne註釋的fetch屬性默認值是FetchType.EAGER。
optional屬性是定義該關聯類對是否必須存在,值爲false時,關聯類雙方都必須存在,如果關係被維護端不存在,
查詢的結果爲null。值爲true時, 關係被維護端可以不存在,查詢的結果仍然會返回關係維護端,在關係維護端
中指向關係被維護端的屬性爲null。optional屬性的默認值是true。

12. 一個EJB3程序一般包含一個服務器端(如JBoss)和一個客戶端(Tomcat或JBoss),客戶端用Tomcat時,客戶端與服務器端不在一個VM內,即使客戶端將服務器端的工程包含了進來,也需要在客戶端創建SessionBean接口,否則會出錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章