2014-11-14 41 views
1

我正在使用JPA和CDI開發JSF應用程序;我用下面的後端架構:使用JPA和CDI的JSF應用程序後端體系結構

  • 控制器(CDI標註爲JSF處理)
  • 服務(CDI註解注入到控制器和其他服務)
  • 的DAO(與EntityManager的處理)

我的問題是,應該如何處理EntityManager和交易? 例如事務(我沒有使用EJB或Deltaspike,所以沒有可用的聲明式事務)應該由服務層管理(對嗎?),但每個數據相關的其他操作都應由DAO處理。那麼應該在哪裏注入EntityManager?

另外,EntityManager是否應請求(或會話或方法)作用域?

感謝, krisy

+0

您應該使用EJB 3的框架,並利用每個工作單元的一個實體管理器,即一個無狀態的實體外觀。 –

回答

1

我會用服務層管理業務邏輯和數據訪問層管理對象關係模型。作爲上述的結果,實體經理和交易應該是DAO的一部分。儘可能縮短交易時間很重要。

決定選擇何種類型的範圍並不明顯,因爲它取決於您的bean /應用程序的性質。一個示例性的使用隨後this介紹,滑動#15:

  • @RequestScoped:DTO /型號,JSF支持bean
  • @ConversationScoped:多步驟的工作流程,購物車
  • @SessionScoped:用戶登錄憑證
  • @ApplicationScoped:數據由整個應用程序共享,高速緩存

正如您所看到的給定bean的範圍和相關實體ma nager對於它所關心的問題是特定的。如果一個給定的bean是請求作用域它的狀態在相同的HTTP會話中爲單個HTTP請求保留。對於會話作用域 bean,狀態通過HTTP會話進行維護。一個例子方法看起來莫名其妙像下面的(僞):

@SessionScoped // conversation, application scoped as well 
public class ServiceImpl implements Service { 
    @Inject 
    private Dao dao; 

    public void createSomething(SomeDto dto) { 
     // dto -> entity transformation 
     dao.create(entity); 
    } 

    public SomeDto getSomething(int id) { 
     SomeEntity entity = em.findById(id); 
     // entity -> dto transformation 
     return dto; 
    } 
} 
@RequestScoped 
@Transactional 
public class DaoImpl implements Dao { 
    @Inject 
    private EntityManager em; //creating em is cheap 

    // TxType.REQUIRED by default 
    public void create(SomeEntity entity) { 
     em.persist(entity); 
    } 

    @Transactional(TxType.NOT_SUPPORTED) 
    public SomeEntity findById(int id) { 
     return em.find(SomeEntity.class, id); 
    } 
} 
+0

是不是@Transactional一個EJB註釋? – krisy

+0

我會說'javax.ejb.TransactionAttribute'是一個EJB註釋,'javax.transaction.Transactional'是一個CDI。從Java EE 7開始,您可以使用'@ Transactional'攔截器以基於CDI的bean的聲明方式控制事務。如果您被綁定到Java EE 6,則需要創建自己的攔截器([示例])(https://blogs.oracle.com/arungupta/entry/totd_151_transactional_interceptors_using))。 – wypieprz

+0

謝謝,正是我所需要的! – krisy