2010-04-22 104 views
2

我使用的是JEE6堆棧包括JPA 2.0,JSF 2.0,EJB 3.1等我正確使用EJB嗎?

的方式我的架構設置如下:

我有JPA使用Hibernate作爲我JPA提供商註釋的DAO。 我有與我的facelet/xhtml頁面相對應的JSF託管bean。 我有處理所有數據庫請求的EJB。

我的XHTML頁面有調用我的託管bean的JSF EL。我的託管bean包含對由EJB管理的DAO實體的引用。例如,我有一個映射到數據庫表的用戶實體。我有一個用戶EJB來處理所有返回用戶的CRUD操作。我有一個編輯用戶的頁面。高級工作流程將是:導航到用戶編輯頁面 - > EL調用位於加載用戶的託管bean中的方法。該方法從EJB調用userEJB.loadUser(user)以從數據庫獲取用戶。用戶被編輯並提交 - >一個函數在託管bean中調用,它調用EJB中的一個函數來保存用戶。等等

我遇到了使用EJB訪問我的JSF頁面中的數據的問題。 我有很多懶惰初始化錯誤的問題,我相信這是由於我已經設置好了。

例如,我有一個客戶端實體,它具有一個延遲加載的用戶列表。爲了得到 一個客戶端,我在我的EJB中調用一個到數據庫的方法,找到一個客戶端並返回它。後來在 我希望訪問這個客戶的用戶列表,爲了做到這一點,我必須通過調用某種方法來加載這些用戶(因爲他們被懶惰地加載)回到EJB。這意味着,我要創建一個方法,如

public List<User> getUserListByClient(Client c) 
{ 
    c = em.merge(c); return c.getUserList(); 
} 

這種方法的唯一目的是加載用戶(我不連陽這種做法是好還是作品)。 如果我自己在做會話管理,我想讓整個請求的會話都打開並直接訪問該屬性,這將會很好,因爲會話將會打開,似乎有一個額外的間接層EJB讓我感到困難。

我喜歡EJB,因爲我喜歡它們受容器控制,共享,提供免費事務管理等事實。但是,我感覺我錯誤地使用它們,或者我已經設置了我的JSF應用程序不正確。

任何反饋將不勝感激。

感謝,

回答

1

您的使用似乎好。請記住,em.merge(c)可能會將對Client c所做的更改保存到數據庫中。如果你只是想獲得客戶端C的UserList的不保存到客戶端C所做的更改,那麼你可以這樣做:

public List<User> getUserListByClient(Client c) 
{ 

    Client client = em.find(Client.class, c.clientId); 
    return client.getUserList(); 

} 

或者更好的,只是給委託人身份證到getUserListByClient強似全客戶端對象,只是爲了節省一個tinsy winsy位的內存:)

2

如果我在做會話管理 我自己,我想剛離開 會話打開整個請求 和直接訪問屬性,這 將罰款作爲會議將是 開放反正

事實上,這就是open session in view模式(也稱爲開放的EntityManager在視圖)。它也可以與EJB一起使用。理想情況下,事務應該在業務層/ EJB中進行管理,因此可以看到這與純層架構略有偏差。但它解決了視圖中延遲加載的問題,並且很容易。

否則,您必須確保急切地加載交易結束後將使用的信息。或者你可以依靠DTO,但是它開始很麻煩。

這裏有兩個覆蓋的話題和討論利弊/利弊和替代鏈接: