【问题标题】:JSF application backend architecture with JPA and CDI使用 JPA 和 CDI 的 JSF 应用程序后端架构
【发布时间】:2015-01-11 13:05:00
【问题描述】:

我正在使用 JPA 和 CDI 开发 JSF 应用程序;我使用以下后端架构:

  • 控制器(JSF 流程的 CDI 注释)
  • 服务(要注入控制器和其他服务的 CDI 注释)
  • DAO(使用 EntityManager 处理)

我的问题是,EntityManager 和事务究竟应该如何处理? 例如事务(我不使用 EJB 或 Deltaspike,因此没有可用的声明性事务)应该由服务层管理(对吗?),但每个与数据相关的其他操作都应该由 DAO 处理。那么EntityManager应该注入到哪里呢?

另外,EntityManager 是否应该是请求(或会话或方法)范围的?

谢谢, 克丽丝

【问题讨论】:

  • 您应该使用 EJB 3 框架,并且每个工作单元使用一个实体管理器,即无状态实体外观。

标签: jsf jpa architecture cdi


【解决方案1】:

我会使用服务层来管理业务逻辑,使用数据访问层来管理对象关系模型。由于上述原因,实体管理器和交易应该是 DAO 的一部分。保持交易尽可能短很重要。

选择哪种范围类型的决定并不那么明显,因为它取决于您的 bean/应用程序的性质。 this 演示后的示例用法,幻灯片 #15:

  • @RequestScoped:DTO/Models,JSF 支持 bean
  • @ConversationScoped:多步骤工作流程,购物车
  • @SessionScoped:用户登录凭据
  • @ApplicationScoped:整个应用共享的数据,缓存

正如您所见,给定 bean 的范围和相关的实体管理器特定于它所关注的问题。如果一个给定的 bean 是 request scoped,那么它的状态会被保存在同一个 HTTP 会话中的单个 HTTP 请求中。对于 session 范围 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);
    }   
}

【讨论】:

  • @Transactional 不是 EJB 注释吗?
  • 我会说javax.ejb.TransactionAttribute 是一个EJB 注释,javax.transaction.Transactional 是一个CDI。从 Java EE 7 开始,您可以使用 @Transactional 拦截器以声明性方式控制基于 CDI 的 bean 的事务。如果您绑定到 Java EE 6,则需要创建自己的拦截器 (an example)。
  • 谢谢你,正是我需要的!
  • 如果有人想用 CDI 实现声明式事务,这里有另一篇文章:link
  • 检查当前登录用户权限的代码应该在哪里?或者任何依赖于当前登录用户的逻辑?
猜你喜欢
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 2012-06-23
  • 2013-05-11
  • 2012-01-19
  • 2014-06-05
  • 2013-05-24
  • 2012-02-11
相关资源
最近更新 更多