no Session问题,即延迟加载

来源:互联网 发布:php视频推荐 编辑:程序博客网 时间:2024/05/22 06:02


no Session问题,即延迟加载

  在开发中,相信很多同学都遇到过这个问题,也就是说当我们在前台页面用表达式语言取值的时候,会发现程序后台报错了,显示的错误时no session,其实这个就是延迟加载的问题,下面进行简单的谈一谈,并提出几点解决的建议。

  延迟加载的问题是指当我们调用完action中的某个方法,在jsp页面要显示我们想要的信息的时候,发现在dao中打开的session已经关闭了。

  如下图,第一个箭头表示的是我们通过前台页面返回action,action会通过service层调用dao去访问数据库,当从数据库中把值取出来之后返回到action中,再返回到前台页面中去。我们知道,只有我们在调用某个类getter()方法的时候才会打开session,可惜的是,在hibernateTemplate中注入的sessionFactory在action返回到前台页面前已经关闭了,也就是这个时候再前台页面调用getter()方法,想要打开session,但是sessionFactory已经关闭了,所以后台就会报错,显示no session。意思就是找不到session。

       

这个时候可以采用以下几种方式解决:

  1、  将pojo类中的fetch的lazy改成eager,这个时候如果你的操作页面中牵扯了多个外键关系的话,就要把这几个外键关系的fetch的lazy都改成eager。这里的lazy是代表懒加载的意思,也就是说在查询一个表的信息的时候,不会把关联的表的信息查找出来。而如果改成eager的话,就代表说把关联的表的信息也全部加载出来。很明显,这样的操作会加载一些我们压根就不需要的操作,也可能我们只需要加载某张表的信息的时候,却自动的把关联的表加载出来。所以这种操作性能是很差的,不建议使用。

  2、  配置过滤器openSessionInViewFilter,顾名思义,这个过滤器是指把在页面中打开session的服务,也就是说延迟session打开的状态,在前台页面中调用完方法之后再关闭session,配置如下: 

<filter>

<filter-name>OpenSessionInView</filter-name>

<filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

</filter>

<filter-mapping>

         <filter-name>OpenSessionInView</filter-name>

         <url-pattern>/*</url-pattern>

</filter-mapping> 

    要注意的是这个过滤器要配置到struts的过滤器的前面,不然就不起作用了,因为配置在struts过滤器的后面的话,数据已经接收完毕了,也就是说sessionFactory已经关闭了,这个时候你再来配置说把session延长到view中,已经没作用了,所以要把openSessionInViewFilter配置在struts前面。但是要注意的是,上面的配置并不是完整的配置,完整的配置应该是在filter里面配置如下信息: 

<filter>

         <filter-name>OpenSessionInView</filter-name>

         <filter-class>

                   org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

         </filter-class>

         <init-param>

                   <param-name>singleSession</param-name>

                   <param-value>true</param-value>

         </init-param>

</filter>

<filter-mapping>

         <filter-name>OpenSessionInView</filter-name>

         <url-pattern>/*</url-pattern>

</filter-mapping> 

    上面配置的意思是表示配置成单例的session。但是如果按以上配置的话,在后续session的操作中是会出现问题的,而如果不配置成单例的话,性能是很低的。所以这个方法也不建议。

  3、  手工操作(建议)  

    a)   在action中操作

    在action中操作指的是我们在传递对象到前台页面(这里主要是jsp)的时候,多传递一些对象到前台去。比如在action中我们需要传递question对象到前台中进行展示,但是同时也需要查找出这个问题所属的类型type,这个时候就可以在页action中除了传递question对象之外,再根据这个question的其他属性(如tid)来查找到对应的type,再把type对象传递到页面中。不过这样做比较麻烦的是除了自己要在dao中加方法外,如果一个页面管理着好几个数据表的话,传递的对象属性相对就比较多了。

    b)   在daoimpl中操作(强烈建议)

  在daoimpl中进行手工设置是本人觉得最合适的方式,也是比较推崇的一种。用这种方法的话,在daoimpl的操作中,就要用到hibernateCallback的内部类方法了。也就是说调用super.getHibernateTemplate().execute()方法,编写内部类,在得到一个list集合之后,取出集合的对象,调用要用到的关联类的getter()方法,就可以打开session了,一般不用调用主键的getter()方法。

范例(只是部分代码,无法运行,仅供参考):

复制代码
 1 public Question findById(final Integer id) throws Exception { 2         return super.getHibernateTemplate().execute( 3                 new HibernateCallback<Question>() { 4                     @SuppressWarnings("unchecked") 5                     public Question doInHibernate(Session session) 6                             throws HibernateException, SQLException { // 用hibernateCallBack 7                         String hql = "From Question AS q WHERE q.qid=?"; // 构建hql语句 8                         Query query = session.createQuery(hql); // 创建query 9                         query.setInteger(0, id); // 设置占位符10                         List<Question> all = query.list(); // 得到具体的list集合,里面只存放一个question对象11                         if (all.size() > 0) { // 集合不为空12                             Question vo = all.get(0); // 取出question对象13                             vo.getType().getTitle(); // 调用type的getTitle方法,这样会把type相关的session打开,在jsp调用时数据还可以调用14                             vo.getAnswers().size(); // 调用getAnswers()方法,把session打开,消除延迟加载15                             if (vo.getAnswer() != null) { // 如果存在最佳答案16                                 vo.getAnswer().getContent(); // 消除延迟加载17                             }18                             return vo; // 返回vo19                         }20                         return null;21                     }22                 });23     }
复制代码





错误
21:22:57,444 DEBUG Loader:384 - Result set row: 0
21:22:57,445 DEBUG Loader:1514 - Result row: EntityKey[cn.itheima.domain.Order#1]
21:22:57,446 DEBUG Loader:384 - Result set row: 1
21:22:57,447 DEBUG Loader:1514 - Result row: EntityKey[cn.itheima.domain.Order#2]
21:22:57,448 DEBUG TwoPhaseLoad:144 - Resolving associations for [cn.itheima.domain.Order#1]
21:22:57,448 DEBUG TwoPhaseLoad:274 - Done materializing entity [cn.itheima.domain.Order#1]
21:22:57,449 DEBUG TwoPhaseLoad:144 - Resolving associations for [cn.itheima.domain.Order#2]
21:22:57,449 DEBUG TwoPhaseLoad:274 - Done materializing entity [cn.itheima.domain.Order#2]
21:22:57,450 DEBUG TransactionImpl:62 - committing
21:22:57,450 DEBUG AbstractFlushingEventListener:132 - Processing flush-time cascades
21:22:57,451 DEBUG AbstractFlushingEventListener:174 - Dirty checking collections
21:22:57,451 DEBUG Collections:184 - Collection found: [cn.itheima.domain.Customer.orders#3], was: [cn.itheima.domain.Customer.orders#3] (uninitialized)
21:22:57,452 DEBUG AbstractFlushingEventListener:106 - Flushed: 0 insertions, 0 updates, 0 deletions to 3 objects
21:22:57,452 DEBUG AbstractFlushingEventListener:113 - Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
21:22:57,453 DEBUG EntityPrinter:102 - Listing entities:
21:22:57,453 DEBUG EntityPrinter:109 - cn.itheima.domain.Order{price=120.00, receiverInfo=南京, orderNum=2, customer=cn.itheima.domain.Customer#3}
21:22:57,454 DEBUG EntityPrinter:109 - cn.itheima.domain.Order{price=110.00, receiverInfo=北京, orderNum=1, customer=cn.itheima.domain.Customer#3}
21:22:57,454 DEBUG EntityPrinter:109 - cn.itheima.domain.Customer{id=3, cusImgsrc=null, cusPhone=567711131, cusName=fox, orders=<uninitialized>}
21:22:57,457 ERROR DefaultDispatcherErrorHandler:42 - Exception occurred during processing request: failed to lazily initialize a collection of role: cn.itheima.domain.Customer.orders, could not initialize proxy - no Session
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: cn.itheima.domain.Customer.orders, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:567)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:205)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:546)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:133)
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:163)
    at com.alibaba.fastjson.serializer.CollectionCodec.write(CollectionCodec.java:74)
    at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:367)
    at com.alibaba.fastjson.serializer.ASMSerializer_2_Customer.write(Unknown Source)
    at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:367)
    at com.alibaba.fastjson.serializer.ASMSerializer_1_Order.write(Unknown Source)
    at com.alibaba.fastjson.serializer.ListSerializer.write(ListSerializer.java:129)
    at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:338)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:488)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:421)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:391)
    at cn.itheima.action.OrderAction.findOrder(OrderAction.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:891)
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1293)
    at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
    at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117)
    at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108)
    at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1369)
    at ognl.ASTMethod.getValueBody(ASTMethod.java:90)
    at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
    at ognl.SimpleNode.getValue(SimpleNode.java:258)
    at ognl.Ognl.getValue(Ognl.java:494)
    at ognl.Ognl.getValue(Ognl.java:458)
    at com.opensymphony.xwork2.ognl.OgnlUtil$2.execute(OgnlUtil.java:309)
    at com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecute(OgnlUtil.java:340)
    at com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:307)
    at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:423)
    at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:287)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:250)
    at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:76)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:253)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:139)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)


阅读全文
0 0