• Hibernate和Spring整合出现懒加载异常:org.hibernate.LazyInitializationException: could not initialize proxy


    出现问题: 

    SSH整合项目里,项目目录结构如下:

    在EmployeeAction.java的list()方法里将employees的list放入到request的Map中。

    EmployeeAction.java:

     1 package com.tt.ssh.actions;
     2 
     3 import java.util.Arrays;
     4 import java.util.Map;
     5 
     6 import org.apache.struts2.interceptor.RequestAware;
     7 
     8 import com.opensymphony.xwork2.ActionContext;
     9 import com.opensymphony.xwork2.ActionSupport;
    10 import com.opensymphony.xwork2.util.ValueStack;
    11 import com.tt.ssh.service.EmployeeService;
    12 
    13 public class EmployeeAction extends ActionSupport implements RequestAware{
    14     private static final long serialVersionUID = 1L;
    15 
    16     private EmployeeService employeeService;
    17         
    18     public void setEmployeeService(EmployeeService employeeService) {
    19         this.employeeService = employeeService;
    20     }
    21     
    22     Map<String, Object> request;
    23 
    24     public String list(){
    25         request.put("employees",employeeService.getAll());
    26         return "list";
    27     }
    28     
    29     @Override
    30     public void setRequest(Map<String, Object> arg0) {
    31         // TODO Auto-generated method stub
    32         this.request = arg0;
    33     }
    34 }

    然后到emp-list.jsp页面上进行获取,发现始终都获取不到employees。

    emp-list.jsp:

     1 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     2 <title>Insert title here</title>
     3 </head>
     4 <body>     
     5        <s:debug></s:debug>
     6  
     7        <center>
     8            <h4>list页面显示成功!</h4>
     9     
    10            <s:if test="#request.employees == null || #request.employees.size() == 0">
    11                  没有任何员工信息
    12            </s:if>
    13            <s:else>
    14                 <table border="1" cellpadding="10" cellspacing="0">
    15                     <s:iterator value="#request.employees" var="employee">
    16                         <tr>
    17                           <td>${employee.id }</td>
    18                           <td>${employee.lastName }</td>
    19                           <td>${employee.email }</td>
    20                           <td>${employee.birth }</td>
    21                           <td>${employee.createTime }</td>
    22                           <td>${employee.department.deptName }</td>
    23                         </tr>           
    24                     </s:iterator>             
    25                 </table>         
    26            </s:else>
    27           
    28        </center>
    29 </body>
    30 </html>

    排除jsp页面问题,于是进入怀疑在EmployeeAction里employees的list压根没放成功。

    运行到第25行就报错,同时从ctx获取ContextMap进而获取request的Map时得到的为null,这说明employees的list确实没有放入到request的Map中。

    报错如下:

    Stacktraces

    org.hibernate.LazyInitializationException: could not initialize proxy - no Session
        org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
        org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
        org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
        com.tt.ssh.entities.Department_$$_javassist_1.toString(Department_$$_javassist_1.java)
        java.lang.String.valueOf(String.java:2994)
        java.lang.StringBuilder.append(StringBuilder.java:131)
        com.tt.ssh.entities.Employee.toString(Unknown Source)
        java.lang.String.valueOf(String.java:2994)
        java.lang.StringBuilder.append(StringBuilder.java:131)
        java.util.AbstractCollection.toString(AbstractCollection.java:462)
        com.tt.ssh.actions.EmployeeAction.list(Unknown Source)
        sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        java.lang.reflect.Method.invoke(Method.java:498)
        ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:871)
        ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1294)
        ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
        com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117)
        com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108)
        ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1370)
        ognl.ASTMethod.getValueBody(ASTMethod.java:91)
        ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
        ognl.SimpleNode.getValue(SimpleNode.java:258)
        ognl.Ognl.getValue(Ognl.java:467)
        ognl.Ognl.getValue(Ognl.java:431)
        com.opensymphony.xwork2.ognl.OgnlUtil$3.execute(OgnlUtil.java:352)
        com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecuteMethod(OgnlUtil.java:404)
        com.opensymphony.xwork2.ognl.OgnlUtil.callMethod(OgnlUtil.java:350)
        com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:430)
        com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:290)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:251)
        org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:168)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
        org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:76)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:253)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
        com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:140)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
        com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
        org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
        org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:575)
        org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
        org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
        org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
        org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
        org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
        org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1100)
        org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687)
        org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2508)
        org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2497)
        java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        java.lang.Thread.run(Thread.java:745)
    

     

     分析原因:

      EmployeeService.java:

     1 package com.tt.ssh.service;
     2 
     3 import java.util.List;
     4 
     5 import com.tt.ssh.dao.EmployeeDao;
     6 import com.tt.ssh.entities.Employee;
     7 
     8 public class EmployeeService {
     9     
    10     private EmployeeDao employeeDao;
    11 
    12     public void setEmployeeDao(EmployeeDao employeeDao) {
    13         this.employeeDao = employeeDao;
    14     }
    15     
    16     public List<Employee> getAll(){
    17         return employeeDao.getAll();
    18     }
    19     
    20 
    21 }

    而EmployeeDao.java:

     1 package com.tt.ssh.dao;
     2 
     3 import java.util.List;
     4 
     5 import org.hibernate.Session;
     6 import org.hibernate.SessionFactory;
     7 
     8 import com.tt.ssh.entities.Employee;
     9 
    10 public class EmployeeDao {
    11     
    12     private SessionFactory sessionFactory;
    13 
    14     public void setSessionFactory(SessionFactory sessionFactory) {
    15         this.sessionFactory = sessionFactory;
    16     }
    17     
    18     public Session getSession(){
    19         return this.sessionFactory.getCurrentSession();
    20     }
    21     
    22     public List<Employee> getAll(){
    23         String hql = "FROM Employee";
    24         return getSession().createQuery(hql).list();
    25     }
    26 
    27 }

      可以看到,employee的list是从Hibernate的session里获取的。

    报错是一个懒加载异常,意识是在session(hibernate里的session)关闭后使用employee对象的未加载变量,也就是说session已经关闭,然而该实例变量却还没有被初始化,就使用了该实例变量,导致该异常。

    applicationContext.xml配置如下:


    由于employee是由hibernate进行加载的,可能hibernate本身是以load的方式将该实例变量得到。此时在employeeDao里session获取到的是
    employee代理类对象,整个Session范围内,应用程序没有访问过employee对象,那么employee代理类的实例一直不会被初始话。事务是作用在EmployeeService上,导致
    List<Employee> getAll( )方法调用之前获取Session、开启事务,这个方法结束之后提交事务、关闭session。session关闭后,在EmployeeAction获取employee时是未初始化的employee代理类对象,未被初始化的代理类对象只有OID其他属性全为null,那么放入request的Map里的是未被初始化的employee代理类对象。一旦在action或者jsp里要获取employee代理类对象,必然会发生懒加载异常。同理,在jsp里获取employee的department时同样存在懒加载的问题。
    (关于hiberante的延迟加载,更详细的在我的另一篇博客里:http://www.cnblogs.com/TTTTT/p/6682304.html)

    解决办法:

    方法1.用openSessionInView 。
    方法2.把这个类的延迟加载禁掉,lazy设为false。
    方法3.迫切左外连接。

  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/TTTTT/p/6682798.html
Copyright © 2020-2023  润新知