Hibernate org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:

前端 未结 3 1555
失恋的感觉
失恋的感觉 2021-01-05 11:25

I have the below mentioned Entity classes, when I execute my application I am getting the following exception. Some of the other similar questions didn\'t solve the problem.

相关标签:
3条回答
  • 2021-01-05 11:53

    I have resolved the issue by adding the following in web.xml

    <filter>
    <filter-name>OpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    courtesy here and here

    Thanks

    0 讨论(0)
  • 2021-01-05 11:58

    The problem is that the scope of your database/JPA transaction only contains the service (which I assume is a stateless session bean) and does NOT contain the REST resource bean.

    1. Web server dispatches request to JAX-RS service
    2. JAX-RS service calls EJB Stateless Session Bean
    3. Transaction starts
    4. EJB Stateless Session Bean loads data from database (other beans might be involved)
    5. EJB Stateless Session Bean returns result
    6. Transaction ends
    7. JAX-RS service returns result
    8. JAX-RS Producer creates XML out of List<Emp> and accesses field empDeptno.

    So when Jersey gets the list of Emp to produce XML out of it, the transaction has already been closed. When now the field empDeptNo is navigated, JPA tries to lazily load it, which fails as we're already outside a valid transaction/session.

    You might try to extend the transaction scope to also contain your Jersey REST resource bean by making a stateless session bean out of it. Then it might be as follows:

    1. Web server dispatches request to JAX-RS service
    2. Transaction starts
    3. JAX-RS service calls EJB Stateless Session Bean
    4. EJB Stateless Session Bean loads data from database (other beans might be involved)
    5. EJB Stateless Session Bean returns result
    6. JAX-RS service returns result
    7. JAX-RS Producer creates XML out of List<Emp> and accesses field empDeptno.
    8. Transaction ends

    I'm not 100% sure, it might also be that step 8 comes BEFORE step 7, so the transaction might be closed before the producer does its job. If that's the case, this solution is simply wrong...

    But I think you should simply try it...

    0 讨论(0)
  • 2021-01-05 12:04

    If you would like to continue using FetchType.LAZY but need access to the lazily loaded attributes for some queries, a portable solution would be to access the field and perform an operation on it while still within a transaction/session. I mention portability because AFAIK Hibernate offers at least one different approach to explicitly trigger loading that is not part of the JPA spec.

    Adapting your code, this could look like this:

    public List<Emp> findAllEmployees() {
      List<Emp> employees = getEntityManager().createNamedQuery("Emp.findAllEmployees",
        Emp.class).getResultList();
    
      //trigger loading of attributes
      for(Emp emp: employees){
        emp.getDeptNo().getEmpDetNo().size();
      }
      return employees;
    }
    

    EDIT: Another portable alternative would be to use fetch joins in the query. Your Emp.findAllEmployees query could look like this:

    SELECT e FROM Emp e JOIN FETCH e.dept.empDetno
    

    Make it a left join if you have Emps without departments and departments without empDetNo

    0 讨论(0)
提交回复
热议问题