我正在使用JPA和CDI处理JSF应用程序;我使用以下后端架构:
我的问题是,应该如何处理EntityManager和事务? 例如,事务(我不使用EJB或Deltaspike,因此没有可用的声明性事务)应该由服务层管理(我是对的吗?),但每个数据相关的其他操作应该由DAO处理。那么应该在哪里注入EntityManager?
另外,EntityManager应该是请求(或会话或方法)作用域吗?
谢谢, krisy
答案 0 :(得分:1)
我会使用服务层来管理业务逻辑和数据访问层来管理对象关系模型。由于上述原因,实体经理和交易应该是DAO的一部分。保持交易尽可能短是很重要的。
决定选择哪种类型的范围并不明显,因为它取决于bean /应用程序的性质。使用示例用法this演示文稿,幻灯片#15:
@RequestScoped
:DTO / Models,JSF支持bean @ConversationScoped
:多步工作流程,购物车@SessionScoped
:用户登录凭据@ApplicationScoped
:整个应用分享的数据,缓存正如您所看到的,给定bean的范围和相关的实体管理器特定于它所关注的问题。如果给定的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);
}
}