• 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.迫切左外连接。

  • 相关阅读:
    hive sql 解析json
    解决华为手机无法安装未签名apk问题(该安装包未包含任何证书)
    对马尔科夫决策过程的代码补充解释
    对马尔科夫决策过程MDP(Markov Decision Processes)的一点理解
    使用Web在PC和安卓之间传输文件(Transfer files via wifi)
    记录下自己的生活状态,昏昏沉沉的半年,迷茫的未来
    __repr__和pass在python中的含义
    LaTeX基础调节,调节行距,字体大小,字体,页边距
    LaTeX怎么让一行中的一部分右对齐
    Tkinter主动刷新(强制刷新)
  • 原文地址:https://www.cnblogs.com/TTTTT/p/6682798.html
Copyright © 2020-2023  润新知