3

我有以下 JSF/PrimeFaces EJB 架构:

[JSF/PrimeFaces xhtml 视图]--> [@ManagedBean JSF bean]--> [@Stateless EJB3 bean]--JPA--> [DB]

也就是说,JSF 视图显示它们在其支持 bean ( @ManagedBean ) 上访问的实体和集合,这些集合和实体又通过调用注入了EntityManager的无状态EJB3 “外观”bean 来获取,并使用由JPA支持的JPA 访问数据库休眠。无状态EJB3 bean 也提供一些服务,但在大多数情况下,它们的作用是根据需要显示它们的xhtml视图的请求,提供来自数据库的实体对象( JPA -annotated)。

现在事情是这样的:如果我的理解是正确的,那么当无状态 EJB3 bean 返回实体 bean 时,它们就会分离,因为每个EJB3 bean 方法都划分了一个事务。通常情况下,当xhtml视图和JSF 托管bean 导航如此获取的 Entity 对象(一对多集合等)的图形时,我经常会遇到如下所示的延迟初始化异常:

javax.el.ELException: ... org.hibernate.LazyInitializationException: failed
to lazily initialize a collection of role: ..., no session or session was closed

唯一可行的是将集合更改为EAGER -ly 加载,但这不是一个实用的解决方案。当分离的 JPA 实体找到通往视图层的方式时,有哪些好的模式可以使用,以避免一劳永逸的延迟初始化异常,而不必以特别的方式处理每种情况?

4

1 回答 1

4

有两种处理惰性关联的方法。第一种方法是使用以下方法初始化实体:

Hibernate.initialize(proxy)

或将获取类型设置为 EAGER,这将在您加载它时获取整个实体。第二种也是更合适的方法(在我看来)是只要您保留实体,就保留实体经理。这可以使用像这样的@Stateful 会话来完成:

@Stateful
public class UserService {
   @PersistenceContext(type=EXTENDED)
   private EntityManager entityManager;

   ...... the business method
}

只要您保留实体,就保留对 ejb 的引用。更多关于扩展持久性上下文的信息可以在这里找到。保留实体管理器的其他方法是使用 CDI 模块,例如seam-persistenceCODI,它们提供了创建 EntityManager 并将其保持在对话范围内的功能。

于 2012-10-26T17:37:07.237 回答