延迟加载 ERROR org.hibernate.LazyInitializationException:42 - could not initialize proxy - ...
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()方法。
范例:
|
public Question findById(final Integer id) throws Exception { return super.getHibernateTemplate().execute( new HibernateCallback<Question>() { @SuppressWarnings("unchecked") public Question doInHibernate(Session session) throws HibernateException, SQLException { // 用hibernateCallBack String hql = "From Question AS q WHERE q.qid=?"; // 构建hql语句 Query query = session.createQuery(hql); // 创建query query.setInteger(0, id); // 设置占位符 List<Question> all = query.list(); // 得到具体的list集合,里面只存放一个question对象 if (all.size() > 0) { // 集合不为空 Question vo = all.get(0); // 取出question对象 vo.getType().getTitle(); // 调用type 的getTitle 方法,这样会把type 相关的session 打开,在jsp 调用时数据还可以调用 vo.getAnswers().size(); // 调用getAnswers() 方法,把session 打开,消除延迟加载 if (vo.getAnswer() != null) { // 如果存在最佳答案 vo.getAnswer().getContent(); // 消除延迟加载 } return vo; // 返回vo } return null; } }); } |
延迟加载 ERROR org.hibernate.LazyInitializationException:42 - could not initialize proxy - ...的更多相关文章
- (org.hibernate.LazyInitializationException:19) - could not initialize proxy错误
(org.hibernate.LazyInitializationException:19) - could not initialize proxy错误 在刚插入数据后,马上使用dao进行query ...
- hibernate延迟加载org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.javakc.hibernate.onetomany.entity.DeptEntity.emp, could not initialize proxy - no Session
public static void main(String[] args) { DeptEntity dept = getDept("402882e762ae888d0162ae888e ...
- org.hibernate.LazyInitializationException: failed to lazily initialize
今天搞了一上午,都在解决这个问题:org.hibernate.LazyInitializationException: failed to lazily initialize 原因很简单,是在非法的s ...
- ssh框架错误:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role。
在做ssh项目练习的时候出现问题: org.hibernate.LazyInitializationException: failed to lazily initialize a collectio ...
- 问题:org.hibernate.LazyInitializationException: failed to lazily initialize
今天搞了一上午,都在解决这个问题:org.hibernate.LazyInitializationException: failed to lazily initialize 原因很简单,是在非法的s ...
- 【HIbernate异常】could not initialize proxy - no Session (已解决)
异常信息: org.hibernate.LazyInitializationException: could not initialize proxy - no Session 解决方法: 用 get ...
- 使用hibernate从一方获取多方信息时报错:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role
引起原因:hibernate加载关联对象的方式有懒加载方式和立即加载方式. 如果在多对一的配置中没有指定加载方式,而一对多的配置中指定了懒加载方式,因此在获取一方是可获取到值,而获取多方时sessio ...
- org.hibernate.LazyInitializationException...no session or session was closed
org.hibernate.LazyInitializationException:failed to lazily initialize a collection of role:cn.its.oa ...
- org.hibernate.LazyInitializationException
1.org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.c ...
随机推荐
- Elasticsearch的PHP的API使用(一)
前提:在服务器上安装Elasticsearch (host:192.168.1.10) http://192.168.1.10:9200?_search?pretty 1:安装PHP的Elast ...
- 树莓派 B+ Yeelink实现图像监控
树莓派 B+ Yeelink实现图像监控 数值传感器请参考 : http://blog.csdn.net/xiabodan/article/details/39084877 1 安装摄像头 ...
- C#流总结(文件流、内存流、网络流、BufferedStream、StreamReader/StreamWriter、TextReader/TextWriter)
一.文件流 FileStream类主要用于读写磁盘文件.常用于向磁盘存储数据或读取配置文件. 读取文件: //文件流:读取 FileStream fileStream = File.Open(@&qu ...
- 【转】java 访问.net webservice返回的数据集
转自[转的也是转的][http://blog.csdn.net/fox123871/article/details/8637839] 1. 概述 很多正在开发或者打算开发XML Web Service ...
- 调用WCF Data Service的几点Tips
使用Linq实现sql in statement的时候,用EF的时候可以通过Contains.Exists的方法实现.但是在使用WCF Data Service的context的时候,会报不支持该方法 ...
- 使用notiy和wait模拟阻塞队列
public class MyQueue { //定义一个存储数据的容器 private LinkedList<Object> list = new LinkedList<Objec ...
- Windows下安装Elasticsearch
1.下载elasticsearch-1.6.0 .jdk-7u67-windows-x64.exe 1.6.0必须用jdk1.7才能运行 2.配置JAVA_HOME:C:\Program Files\ ...
- Varint编码
LevelDB内部通过采用变长编码,对数据进行压缩来减少存储空间,采用CRC进行数据正确性校验.下面就对varint编码进行学习. 传统的integer是以32位来表示的,存储需要4个字节,当如果整数 ...
- ThinkPHP之中的图片上传操作
直接上个例子,其中包括有单图片文件上传.多图片文件上传.以及删除文件的一些操作.放置删除数据库的时候,仅仅删除掉了数据库之中的文件路径.而不是一并删除服务器之中的文件.放置服务器爆炸... TP里面c ...
- Nob畅想在线教育
1.社交网络的课堂实时互动 老师上课,每当和同学们互动时大家下边总是保持沉默,低着头,几乎每人拿着一部手机在看,还有pad等. 张星老师的课算是好一点,学生可以抬着头然后手下边捏着手机,时不时低头看一 ...