解决hibernate报错:no-session的问题
1.问题描述:对于根据id查询时,在dao通过load方式查询对象时,加载页面会报 noSession异常。
严重:Servlet.service()forservlet[springDispatcherServlet]incontextwithpath[/Xxxx]threwexception[Requestprocessingfailed;nestedexceptionisorg.hibernate.HibernateException:NoSessionfoundforcurrentthread]withrootcauseorg.hibernate.HibernateException:NoSessionfoundforcurrentthreadatorg.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)atorg.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:988)atcom.vincent.videosys.dao.BaseDao.getSession(BaseDao.java:17)atcom.vincent.videosys.dao.UserDao.usernameExist(UserDao.java:29)atcom.vincent.videosys.service.UserService.usernameExistService(UserService.java:19)atcom.vincent.videosys.controller.home.UserController.usernameExist(UserController.java:40)atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)atsun.reflect.NativeMethodAccessorImpl.invoke(UnknownSource)atsun.reflect.DelegatingMethodAccessorImpl.invoke(UnknownSource)atjava.lang.reflect.Method.invoke(UnknownSource)atorg.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)atorg.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)atorg.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle
2.问题分析:当使用hibernate框架操作数据库的时候,如果做查询的话会有立即加载(get)和延迟加载(load)的区别,延迟加载表示,当你查询某个数据(假设是对象)的时候,hibernate不会立马发送sql语句,而是当我们调用这个对象的属性的时候,也就是真正使用查询出来的数据的时候才会发送sql语句去一级缓存(即session,这里的session和域对象session没有半毛钱关系)中获取,但是正常这个session的开启核关闭是在service层执行的,但是我们真正使用查询的对象的数据时,是在web层,但是这个时候session已经关闭,就会报no-session异常。
noSession分析图(右键"查看图像"查看原图)
3.问题解决思路
方案一:让session的关闭时间要在web层使用完之后。 但是web层已经是最后一层了,怎么办?还有比web更后的东西哦,就是过滤器, 所以在web.xml中配置开启和关闭session的过滤器即可 ,但是要配在struts的过滤器之前,否则无效。
<filter><filter-name>OpenSessionInViewFilter</filter-name><filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping><filter-name>OpenSessionInViewFilter</filter-name><url-pattern>*.action</url-pattern></filter-mapping>
添加过滤器解决noSession分析图
使用load方法的解决方案 : 就是把原CustomerService层的绑定的session对象 提取配置到前面的 过滤器中了。
方案二:
load改用get立即加载方式查询对象。
packagecn.xdf.dao.impl;@RepositorypublicclassCustomerDaoImplimplementsCustomerDao{@AutowiredrivateHibernateTemplatehibernateTemplate;publicvoidsave(Customercustomer){hibernateTemplate.save(customer);}publicList<Customer>findAll(){return(List<Customer>)hibernateTemplate.find("fromCustomer");}publicvoiddelete(Customercustomer){hibernateTemplate.delete(customer);}//根据id立即加载publicCustomerget(LongcustId){returnhibernateTemplate.get(Customer.class,custId);}//根据id延迟加载-->用该方法会有问题(页面报错:noSession)publicCustomerload(LongcustId){returnhibernateTemplate.load(Customer.class,custId);}publicvoidupdate(Customercustomer){hibernateTemplate.update(customer);}publicList<Customer>findByCriteria(DetachedCriteriadc){return(List<Customer>)hibernateTemplate.findByCriteria(dc);}}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。