JSF / EJB3避免了视图层中的延迟初始化异常

时间:2012-10-26 15:29:14

标签: jsf ejb

我有以下JSF / PrimeFaces EJB架构:

[JSF / PrimeFaces xhtml view] - > [@ManagedBean JSF bean] - > [@Stateless EJB3 bean] --JPA - > [dB]的

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

现在就是这样:如果我的理解是正确的,那么当无状态EJB3 bean返回Entity bean时,它们就会分离,因为每个 EJB3 bean方法都划分了一个事务。然后经常会出现这样的情况: xhtml 视图和 JSF Managed bean导航如此获取的Entity对象的图形(One-To-Many集合等),我经常得到如下的Lazy Initialization异常:

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

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

1 个答案:

答案 0 :(得分:4)

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

Hibernate.initialize(proxy)

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

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

   ...... the business method
}

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