org.hibernate.LazyInitializationException: could not initialize proxy - no Session

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了org.hibernate.LazyInitializationException: could not initialize proxy - no Session相关的知识,希望对你有一定的参考价值。

错误页面提示

could not initialize proxy - no Session

控制台

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

病症:这是一个lazy使用后的Exception,使用迟时加载,在session(hibernate里的session),关闭后使用该对象的未加载变量,也就是说session已经关闭,没有保存到内存中,然后你使用了,导致该异常。

Q:我以get得到一个对象,在JSP页面以EL表达它的实例变量时,也抛出了该异常,在application的测试时却没有出现。
A:推测可能是该实例变量是hibernate进行加载的,可能hibernate本身是以load的方式将该实例变量得到。
解决方法:

方法1.用openSessionInView
方法2.把这个类的延迟加载禁掉

我自己的代码就多了这么一句话:

resultExchangeRatePojo.getDollarRmb();//在它的实例变量DollarRmb的session未关闭前存入,实际上将它载入内存。(我就想在没用关闭session之前用一下就可以把值保存到内存中了)

结果:果然页面上就正常显示了。

总结:原因是hibernate的session已经关闭,集合没有被初始化。在hibernate中:hibernate3 默认支持延迟加载(lazy="proxy"我们可以把proxy看作是true),hibernate2 默认立即加载 (lazy="false")。

在hibernate3中,所有的实体设置文件(user.hbm.xml)中的lazy属性都被默认设成了true,就是当这个类没有被调用时,延时加载,导致了以上情况的发生,在配置文件中将lzay属性设为false就可以了。
原因:
<may-to-one>or<one-to-may>的lazy属性默认为:lazy = "proxy"
解决:<many-to-one> & <set> 中设置 lazy="false"

如果还不行,根据自己需求,经过我的仔细排查放在set一端不行,那就放在<many-to-one>那端

参考资料:http://hi.baidu.com/362217990/blog/item/4c4aabee2b9cf5e6ce1b3ea4.html

参考技术A 这句错误提示的意思是:程序不能初始化,没有收到会话信息。
如果电脑出现这样的问题,一般是内存的问题,需要换根内存条解决问题。
内存是电脑的记忆部件,用于存放电脑运行中的原始数据、中间结果以及指示电脑工作的程序。
内存可以分为随机访问存储器和只读存储器,前者允许数据的读取与写入,磁盘中的程序必须被调入内存后才能运行,中央处理器可直接访问内存,与内存交换数据。电脑断电后,随机访问存储器里的信息就会丢失。后者的信息只能读出,不能随意写入,即使断电也不会丢失。
由于电路的复杂性因素,电脑中都使用二进制数,只有0和1两个数码,逢二进一,最容易用电路来表达,比如0代表电路不通,1代表电路通畅。人们平时用电脑时感觉不到它是在用二进制计算是因为电脑会把人们输入的信息自动转换成二进制,算出的二进制数再转换成人们能看到的信息显示到屏幕上。
在存储器中含有大量的基本单元,每个存储单元可以存放八个二进制位,即一个零到二百五十五之间的整数、一个字母或一个标点符号等,叫做一个字节。存储器的容量就是以字节为基本单位的,每个单元都有唯一的序号,叫做地址。中央处理器凭借地址,准确地操纵着每个单元,处理数据。由于字节这个单位太小了,所以人们定义了几个更大的单位,这些单位是以2的十次幂做进位,单位有KB、MB、GB、TB等。
常见的内存包括同步动态随机存储器、双倍速率同步动态随机存储器、接口动态随机存储器。
参考技术B get是当你调用get的时候就去操作数据库load不一样当使用session中的load方法查询数据库中的记录时,我们返回的是一个代理对象,而不是真正需要的那个对象;例如数据库中存有个Student表,我们有cn.binyulan.doman.Student的领域对象,如果查询Id值为“ ”的Studentstu=(Student)session.load(Student.class," "),然后我们打印System.out.println(stu.getClass);得到的结果为Student$$EnhancerByCGLIB$$ a cc ,名字很奇怪吧,这个对象是Hibernate帮我们生成的,从名字可以看出它是对Student类的增强类的对象,其实这就是个代理对象,这个对象里并没有我们需要的Student的数据,所以如果你在session关闭后在使用stu来获取信息,如stu.getId();就会出现如下异常:org.hibernate.LazyInitializationException:couldnotinitializeproxy-noSession,这就说明了stu中没有我们需要的数据了。hibernate这样做我想是为了节约资源吧如果你查出来了。。然后还没用程序就结束了(比如方式异常)那就浪费了。。毕竟读数据库是一件比较伤的事情代理的作用主要是用来AOP编程的即面向切面编程这个你直接查AOP百度百科就应该有很详细的解释了 参考技术C 这个是hibernate的延迟加载异常,为了不产生该异常,有如下解决方法:

1、在相应的映射文件里禁止该类的延迟加载:设置lazy=false

2、在session关闭之前取出需要的属性

3、使用openSessionInView

<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>
参考技术D 我也出现过这种情况,但是每次解决的方法都不一样 :有可能是有一个什么ant . (记得不清楚反正在前面几个中)的包多了,删除就可以了 :记得有一次我删除了也不管用,结果重新写一下程序就好了 :还有就是在hibernate的配置文件里面写错什么东西了

以上是关于org.hibernate.LazyInitializationException: could not initialize proxy - no Session的主要内容,如果未能解决你的问题,请参考以下文章