2013-07-03 38 views
6

這是我目前更多的體系結構問題。我需要關於在項目上集成EJB和JPA的最佳實踐方面的幫助。我想要有EJB來完成服務層的工作,包含我的應用程序的業務邏輯。在這之下,我想要一個DAO層,我的EJB將使用DAO工廠來處理,以儘可能地分離這兩個層。知道這一點,我顯然不能讓我的DAO成爲EJB,因爲我不希望它們自動注入,因爲我希望它們是通過工廠創建的。這使我創建使用JPA與EJB分離的DAO和服務層

Persistence.createEntityManagerFactory("PortalEJB").createEntityManager(); 

現在手動EntityManager的......這個調用位於我的抽象JPA DAO:

public abstract class JPADataAccessorObject<K, E> implements DataAccessorObject<K, E> { 
    protected Class<E> entityClass; 

    protected EntityManager entityManager; 

    protected JPADataAccessorObject(Class<E> pEntityClass) { 
     this.entityManager = Persistence.createEntityManagerFactory("PortalEJB").createEntityManager(); 
     this.entityClass = pEntityClass; 
    } 

    /* Other DAO functions (update, delete, create) */ 
} 

我覺得這是不好的,不是嗎?這個類的所有具體範圍都會有一個全新的持久化上下文副本,我會得到奇怪的行爲。此外,當我這樣做,我認爲我必須在服務層自己管理事務。我正要創建該方面,是這樣的:

  • 創建任何服務層的功能之前,交易/過程
  • (如果發生任何異常回滾事務)
  • 任何服務層的功能後,提交事務/程序

因此,這裏是我的問題:

  • 我應該怎樣MANAG e EntityManager?
  • 我應該有某種JPA實用程序類,它將管理它有一個受多線程保護的副本嗎?
  • 如果我犯了一個可怕的錯誤,請提供最佳實踐。
+0

哪個版本的Java EE? –

+0

我在GlassFish 3.1上使用EJB 3.1,Java 1.6,JPA 2.0(EclipseLink) –

回答

5

您是否看到過Adam Bien JPA/EJB3 KILLED THE DAODAOS AREN'T DEAD - BUT THEY EITHER COLLAPSED OR DISAPPEARED

在另一隻手,你可以考慮一個抽象類爲服務層:

public abstract class AbstractFacade<E extends Serializable, 
            PK extends Serializable> { 

    private final transient Class<E> entityClass; 

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

    protected abstract EntityManager getEntityManager(); 

    public void create(final E entity) { 
     final EntityManager entityManager = getEntityManager(); 
     entityManager.persist(entity); 
    } 

    public final E find(final PK id) { 
     return getEntityManager().find(entityClass, id); 
    } 

    // Other common operations 

} 

和特定服務

@Stateless 
public class UserFacade extends AbstractFacade<User, String> { 

    @PersistenceContext(unitName = "MyPU") 
    private EntityManager em; 

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

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

    // Other methods of this service 

} 

在舊金山見多Java EE 6/7: The Lean Parts從JavaOne大會2012 。

+0

在你的例子中,你的服務層依賴於JPA,在我看來,這是一件壞事。假設你有來自舊大型機的用戶,他們會將它們「轉儲」到FTP服務器上。使用DAO工廠,您可以擁有一個FTPUserDAO和JPAUserDAO,它們將成爲UserDAO的擴展。你提出的方式,你將不得不有一個全新的FTP服務層。現在,如果你的用戶有一個非常複雜的業務算法呢? –

+1

沒有問題。您可以爲您的遺留系統創建一個特定的工廠,並將其注入CDI。 –

+0

我不同意這一點。根據我的觀點,將DAO和服務分開是比較安全的。儘管你的最後一個鏈接,在視頻的開始,這個傢伙搜索JSF JPA教程,並有一個很好的教程,正是我需要的! http://wiki.eclipse.org/EclipseLink/Examples/JPA/JSF_Tutorial –