2011-04-12 69 views
14

我想問一下在訪問EJB Session Bean時使用Facade模式的原因是什麼。在我的Netbeans 6.9.1,如果我做New>Sessions Bean for Entity Classes,讓說,我選擇User實體,然後Netbeans的將生成的代碼爲什麼使用Facade模式的EJB會話bean

AbstractFacade.java 
public abstract class AbstractFacade<T> { 
    private Class<T> entityClass; 

    public AbstractFacade(Class<T> entityClass) { 
     this.entityClass = entityClass; 
    } 

    protected abstract EntityManager getEntityManager(); 

    public void create(T entity) { 
     getEntityManager().persist(entity); 
    } 

    public T edit(T entity) { 
     return getEntityManager().merge(entity); 
    } 

    public void remove(T entity) { 
     getEntityManager().remove(getEntityManager().merge(entity)); 
    } 

    public T find(Object id) { 
     return getEntityManager().find(entityClass, id); 
    } 

    public List<T> findAll() { 
     javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     cq.select(cq.from(entityClass)); 
     return getEntityManager().createQuery(cq).getResultList(); 
    } 

    public List<T> findRange(int[] range) { 
     ... 
    } 

    public int count() { 
     ... 
    } 

UserFacade.java  

package com.bridgeye.ejb; 

import javax.ejb.Stateless; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

@Stateless 
public class UserFacade extends AbstractFacade<User> { 
    @PersistenceContext(unitName = "Bridgeye2-ejbPU") 
    private EntityManager em; 

    @Override 
    protected EntityManager getEntityManager() { 
     return em; 
    } 

    public UserFacade() { 
     super(User.class); 
    }   
} 

我想問的是什麼這樣做的好處。如果我有10個實體,那麼Netbeans會生成10個Facade類和AbstractFacade。這對我來說似乎有點矯枉過正。讓地方說我管理的bean裏面,我有一個persistUser然後School我已經做到這一點

someManagedBean.java 

... 
@EJB 
private UserFacade userEJB; 

@EJB 
private SchoolFacade schoolEJB; 

... 

public void someMethod(User user, School school){ 
    ... 
    userEJB.create(user); 
    schoolEJB.create(school);  
} 

這是做正確的事?

回答

22

根本上使用EJB的一點是,它們通過註釋(或XML配置)提供了諸如聲明性事務和安全性等功能。如果您不使用這些功能,那麼使用EJB就沒有意義。

此外,自動生成的門面代碼只是一個起點(和一個壞的)。 EJB應該形成一個域API,而不是所有單獨的CRUD操作的包裝。他們應該只包含您實際想要在您的域模型上執行的操作,其中許多操作應該跨越需要在事務中執行的多個CRUD操作。例如:

@TransactionAttribute 
public void transferUser(User u, School from, School to){ 
    from.getUsers().remove(u); 
    to.getUsers().add(u); 
    u.setSchool(to); 
    getEntityManager().merge(from); 
    getEntityManager().merge(to); 
    getEntityManager().merge(u); 
} 

應用服務器將在交易,這確保了,例如內執行的所有操作,你不能有地方將拋出一個異常出於某種原因的情況和你最終用戶被刪除從一個Schoold,但沒有添加到另一個。

+0

我還是有點困惑。我創建EJB的原因是因爲我需要與JPA交互來執行CRUD,比如'persist'或'merge'或'Query#getResultList',所以在這種情況下,我應該使用EJB。我使用'@ Statsless' EJB順便說一句。你能詳細說一下你的第二段,也許是一些示例代碼,所以我可以看到實際的結構,將不勝感激。 – 2011-04-12 14:49:53

+2

@Harry:你不需要使用EJB來使用JPA,你可以直接訪問EntityManager。但是使用EJB獲取事務可能還是有意義的。我會添加一個例子。 – 2011-04-12 14:59:25

+0

謝謝。如果可能的話,你會添加一個如何正確實現EJB的facade模式的例子嗎?我將不勝感激它:D – 2011-04-12 15:02:47

7

是和否。 Facade模式很有意義,但是爲每個域對象分別設置一個facace是沒有意義的。

您將希望爲域對象的每個功能組分組門面。設想一個計費系統。它有賬單,物品,客戶,地址。因此,您可能會在那裏爲賬單處理(添加項目,設置客戶,打印,標記爲已付款)的Facade和用於創建和更新用戶的不同外觀,與地址關聯等。

1

我想你應該有一個AbstractFacade用於典型的CRUD操作,正如你可以看到的,以及許多用於操作給定實體的SpecificFacade。所以你不能只用一次重複實現相同的基本邏輯......而僅僅關注與實體關聯的更復雜的邏輯(事務)。

相關問題