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

Hiberante异常之org.hibernate.LazyInitializationException: could not initialize proxy - no Session

程序员文章站 2022-04-18 22:17:30
...

1、异常描述

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

备注:

      此处hibernate版本号3.6.10.Final

2、示例代码:

2-1 Clazz.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- 用来映射实体类和表的对应关系
    	class="实体类的全路径"
    	table="实体类对应的表名"
     -->
    <class name="cn.wang.entity.Clazz" table="hibernate_class">
        <!-- 映射主键列
             name="主键列对应的属性名"
             column="主键列名"
             type="属性的数据类型"
         -->
        <id name="id" column="id" type="java.lang.Integer">
            <!-- 主键的生成方式 
               class="assigned"   由应用程序自己生成
            -->
           <generator class="assigned"/>
        </id>
        <!-- 映射普通列  方式1:-->
        <property name="name" type="java.lang.String" column="name"/>
    </class>
    
</hibernate-mapping>

 

2-2 ClazzDao.java

    /**
	 * 根据班级id查询班级对象     load方法
	 * @param clazzId
	 * @return
	 */
	public Clazz findByIdLoad(int clazzId){
		// 1、创建session
		Session session = sessionFactory.getCurrentSession();
	        // 2、开启事务
		Transaction transaction = session.beginTransaction();
		// 3、单查
		// 参数1:要查询的类型的类对象   
		// 参数2:要查询的对象的id
		Clazz clazz = (Clazz)session.load(Clazz.class, clazzId);
		// 4、提交事务
		transaction.commit();
		return clazz;
	}

 

2-3 测试类 TestClazzDao.java

    @Test // 测试单查   session.load()
	public void testFindByIdLoad(){
		Clazz clazz = clazzDao.findByIdLoad(1001);
		System.out.println(clazz);
	}

错误原因:

1) 首先,需要了解hibernate中延迟加载的概念

    所谓延迟加载就是当在真正需要数据的时候。才真正执行数据加载操作。

    延迟加载,也称为懒加载,是Hibernate3 对象默认的加载方式。

    延迟加载机制是为了避免一些无谓的性能开销而提出来的

 

 2)在hibernate中,load()方法支持延迟加载。而我们的实体类本身就是支持延迟加载的

   所以在findByIdLoad()方法中,Clazz clazz = (Clazz)session.load(Clazz.class, clazzId); 此行代码并不会立即执行select语句,

   而是在测试类中,System.out.println(clazz);此行代码表示第一次使用到clazz对象。

   当此时再去执行select语句时,session已经关闭,所以会报此错误。

 

3、解决方法

由于session.load() 方法本身支持延迟加载,所以如果为了在session关闭之前立即执行select查询语句,我们可以关闭实体类对象的延迟加载功能,这样,就保证session关闭之前一定执行了select查询。

 

修改 Clazz.hbm.xml 的配置:  在<class> 属性上添加 lazy="false" 即可

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- 用来映射实体类和表的对应关系
    	class="实体类的全路径"
    	table="实体类对应的表名"
  
        lazy="false"  表示关闭Clazz对象的延迟加载功能
        lazy="true"   表示开启Clazz对象的延迟加载功能  默认为true

     -->
    <class name="cn.wang.entity.Clazz" table="hibernate_class" lazy="false">
        <!-- 映射主键列
             name="主键列对应的属性名"
             column="主键列名"
             type="属性的数据类型"
         -->
        <id name="id" column="id" type="java.lang.Integer">
            <!-- 主键的生成方式 
               class="assigned"   由应用程序自己生成
            -->
           <generator class="assigned"/>
        </id>
        <!-- 映射普通列  方式1:-->
        <property name="name" type="java.lang.String" column="name"/>
    </class>
    
</hibernate-mapping>

这样的话,就避免了该种类型的异常

 

此文希望可以帮助到大家。如有错误,请指教。                                                           

如果大家还有其他的情况或者好的解决方法,也望指教,感谢阅读。