出現問題:
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.迫切左外連接。


