欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-17 22:37:35
...

问题内容:

在通过懒加载的方式通过代理对象获取一个model类的多对一的关联配置的时候报如下错误:

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

	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
	at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
	at com.bwol.pm.project.entity.FlowComb_$$_javassist_38.getFlowList(FlowComb_$$_javassist_38.java)

	at com.bwol.common.controller.IndexController.topSelectChange(IndexController.java:868)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
public class IndexController  extends SpringControllerSupport{
	Milestone mileStone = this.getMilestoneBySession();
	List<FlowFlow> flowList = mileStone.getFlowComb().getFlowList();
}

hibernate的配置

 <class name="com.bwol.pm.project.entity.Milestone" table="T_PROJECT_MILESTONE">
        <id name="id" type="java.lang.Long">
            <column name="MS_ID" precision="16" scale="0" />
            <generator class="native" />
        </id>
			省略很多配置信息.......
        <many-to-one name="flowComb" class="com.bwol.pm.project.entity.FlowComb" fetch="select">
            <column name="COMB_ID" precision="16" scale="0" />
        </many-to-one>
    </class>

问题分析

bug报错的原因是:Hibernate的session 关闭了,要从一个懒加载代理对象中获取数据就会报这个错。

我的程序中是通过hibernate获取到Milestone的代理对象,然后将其保存在HttpRequest的session中。在调用MilestoneDao里Hibernate session获取到的是的Milestone代理类对象,整个Session范围内,应用程序没有访问过Milestone对象,只是保存在了HttpRequest的session中。那么Milestone代理类的实例一直不会被初始化。事务是作用在MilestoneService上,导致其在获取Milestone调用之前获取Session、开启事务,这个方法结束之后提交事务、关闭session。session关闭后,在别的地方获取Milestone时是未初始化的Milestone代理类对象,未被初始化的代理类对象只有OID其他属性全为null,在通过Milestone获取其他的多对一数据时,必然会发生懒加载异常。

解决方式

首先感谢 博客园 阳台煮酒 博主提供的解决问题的博客 https://www.cnblogs.com/TTTTT/p/6682798.html 并且博主给出了3个解决方案,但是我都没有采用,我简单暴力的在通过 milestoneService调用getById的方式再次获取一次成功解决问题。代码的操作方式如下:

		Milestone mileStone = this.getMilestoneBySession();
		Long mileId = mileStone.getId();
		mileStone = milestoneService.getById(mileId);
		List<FlowFlow> flowList = mileStone.getFlowComb().getFlowList();