【问题标题】:JSF / EJB3 avoiding lazy initialization exceptions in the view layerJSF/EJB3 避免视图层中的延迟初始化异常
【发布时间】:2012-10-16 21:27:17
【问题描述】:

我有以下 JSF/PrimeFaces EJB 架构:

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

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

现在事情是这样的:如果我的理解是正确的,当实体 bean 被无状态 EJB3 bean 返回时,它们变得分离,因为每个 EJB3 bean 方法划分了一个事务。通常情况下,当 xhtml 视图和 JSF Managed 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 实体找到通往视图层的方式时,有哪些好的模式可以使用,以避免一劳永逸的延迟初始化异常,而不必以特别的方式处理每种情况?

【问题讨论】:

标签: jsf ejb


【解决方案1】:

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

Hibernate.initialize(proxy)

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

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

   ...... the business method
}

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

【讨论】:

    猜你喜欢
    • 2012-11-01
    • 2012-07-27
    • 2014-03-21
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多