Hibernate和Spring整合出現懶加載異常:org.hibernate.LazyInitializationException: could not initialize proxy - no Session


出現問題: 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM