2014-11-14 39 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