出现问题:
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.迫切左外连接。