Jsf 2 从实体延迟加载集合时发生异常

Jsf 2 从实体延迟加载集合时发生异常,jsf-2,jpa-2.0,java-ee-6,cdi,entitymanager,Jsf 2,Jpa 2.0,Java Ee 6,Cdi,Entitymanager,我担心我错过了一个非常基本的观点,但我现在陷入了困境,希望有人能把我的眼睛对准正确的方向。。。 我试着一步一步地完成我的应用程序设置,让自己明白(希望人们在发帖结束之前不会感到无聊): 我有一个会话范围的CDI组件作为JSF2.0视图的处理程序。它包含一个实体管理器、一个对象列表和一个特殊的单个对象: @Named @SessionScoped public class EventHandler implements Serializable { @PersistenceContext

我担心我错过了一个非常基本的观点,但我现在陷入了困境,希望有人能把我的眼睛对准正确的方向。。。 我试着一步一步地完成我的应用程序设置,让自己明白(希望人们在发帖结束之前不会感到无聊):

我有一个会话范围的CDI组件作为JSF2.0视图的处理程序。它包含一个实体管理器、一个对象列表和一个特殊的单个对象:

@Named
@SessionScoped
public class EventHandler implements Serializable {

  @PersistenceContext
  private EntityManager em;

  private List<MyEvent> events;

  private MyEvent currentEvent;
  ...
在上述集合和引用中使用的实体中,存在一个默认情况下被延迟加载的关系:

@ManyToMany(mappedBy="supportedServices")
public Set<MyEntity> getSupportingEntities() {
  ...
我得到一个org.hibernate.LazyInitializationException,告诉我会话已关闭


当处理程序是会话作用域并通过查询加载引用时,处理程序不应该在第二个视图的稍后点加载请求的关系吗?

嗯,我认为这是因为persistenceContext事件(如果它是会话作用域bean的成员)不是会话作用域。
第一次调用视图时,将创建持久性上下文,加载实体(事件)并填充数据表。然后刷新、关闭持久性上下文,并将响应发送到客户端。这一切都发生在同一个http请求中

但是,当您随后调用details视图时,会发出另一个http请求,并创建另一个持久性上下文,并且对“currentEvent”的引用不再附加到最后一个持久性上下文。因此出现LazyInitializationError(必须将实体管理为延迟加载)

解决办法可以是:

  • 使用扩展持久性上下文()
  • 获取关系:

    @ManyToMany(mappedBy=“supportedServices”,fetch=FetchType.EAGER)

  • 在详细信息视图中使用分离的currentEvent实例之前,先将其合并:

    entityManager.merge(currentEvent)


    • 嗯,我认为这是因为persistenceContext事件(如果它是会话范围bean的成员)不是会话范围。
      第一次调用视图时,将创建持久性上下文,加载实体(事件)并填充数据表。然后刷新、关闭持久性上下文,并将响应发送到客户端。这一切都发生在同一个http请求中

      但是,当您随后调用details视图时,会发出另一个http请求,并创建另一个持久性上下文,并且对“currentEvent”的引用不再附加到最后一个持久性上下文。因此出现LazyInitializationError(必须将实体管理为延迟加载)

      解决办法可以是:

      • 使用扩展持久性上下文()
      • 获取关系:

        @ManyToMany(mappedBy=“supportedServices”,fetch=FetchType.EAGER)

      • 在详细信息视图中使用分离的currentEvent实例之前,先将其合并:

        entityManager.merge(currentEvent)


      谢谢您的提示。但是,无论是使用type=PersistenceContextType.EXTENDED还是将其再次合并到em中,都无法完成这项工作,在映射中使用即时抓取是不可能的。但我看到,如果在操作处理程序中设置currentEvent时触碰该关系,它就会工作。尽管如此,我还是不明白为什么em以后不能加载实体的部分。因为我还没有找到其他解释,我将接受你的回答。谢谢你的提示。但是,无论是使用type=PersistenceContextType.EXTENDED还是将其再次合并到em中,都无法完成这项工作,在映射中使用即时抓取是不可能的。但我看到,如果在操作处理程序中设置currentEvent时触碰该关系,它就会工作。尽管如此,我还是不明白为什么em以后不能加载实体的部分。因为我还找不到其他解释,我将接受你的回答。
      <h:dataTable value="#{eventHandler.events}" var="_var">
        ...
          <h:commandLink action="#{eventHandler.linkAction(_var)}"> ... </h:commandLink>
      
      public void setCurrentEvent(MyEvent currentEvent) {
        this.currentEvent = currentEvent;
        ...
      
      @ManyToMany(mappedBy="supportedServices")
      public Set<MyEntity> getSupportingEntities() {
        ...
      
      #{eventHandler.currentEvent.supportingEntities...}