懒加载异常 处理方法

首先看一下什么是懒加载:

所谓懒加载(lazy)就是延时加载,延迟加载。

什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载。

至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,

因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,

我们让数据在需要的时候才进行加载,这时我们就用到了懒加载。

比如部门ENTITY和员工ENTITY,部门与员工1对多,如果lazy设置为 false,那么只要加载了一个部门的po,就会根据一对多配置的关系把所有员工的po也加载出来。但是实际上有时候只是需要用到部门的信息,不需要用到 员工的信息,这时员工po的加载就等于浪费资源。如果lazy设置为true,那么只有当你访问部门po的员工信息时候才回去加载员工的po的信息。

hibernate3.0中lazy有三个值,true,false,proxy,默认的是lazy="proxy".

具体设置成什么要看你的需求,并不是说哪个设置就是最好的。

假如在student对象中包含一个head对象

如果你确定在用student对象的时候就要用到head对象里的属性,那你就设置立即加载,因为设置立即加载那么在查询student的同时就会查询 student的head,hibernate就会在查询的时候关联两张表从而生成的sql就可能只有一条。而如果你设置的是延迟加载,那么肯定会要生成 1+N条sql语句:其中“1”是查询student的语句,“N”是根据N个student的id去查询head的N条语句。而且,延迟加载是要用到的 时候才去执行查询,这样系统判断那里需要加载,那里不需要加载也需要时间,性能上肯定就不如立即加载了!

如果,你是有的地方需要用到student的时候才用到head属性,那么你就设置成延迟加载,因为查询2张表的数据肯定要比查询1张表的数据消耗大。

到低要怎样设置就要看你的实际需求了

延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。

A、实体对象的延迟加载

如果想对实体对象使用延迟加载,必须要在实体的映射配置文件中进行相应的配置,如下所示:

<hibernate-mapping>

 <class name=”com.neusoft.entity.User” table=”user” lazy=”true”>

 ……

 </class>

</hibernate-mapping>

 通过将class的lazy属性设置为true,来开启实体的延迟加载特性。如果我们运行下面的代码:

    User user=(User)session.load(User.class,”1”);(1)

    System.out.println(user.getName());(2)

  当运行到(1)处时,Hibernate并没有发起对数据的查询,如果此时通过一些调试工具,观察此时user对象的内存快照,会惊奇的发现,此时返 回的可能是User$EnhancerByCGLIB$$bede8986类型的对象,而且其属性为null,这是怎么回 事?session.load()方法会返回实体对象的代理类对象,这里所返回的对象类型就是User对象的代理类对象。在Hibernate中通过使用 CGLIB,来实现动态构造一个目标对象的代理类对象,并且在代理类对象中包含目标对象的所有属性和方法,而且所有属性均被赋值为null。通过调试器显
示的内存快照,可以看出此时真正的User对象,是包含在代理对象的CGLIB$CALBACK_0.target属性中,当代码运行到(2)处时,此时 调用user.getName()方法,这时通过CGLIB赋予的回调机制,实际上调用CGLIB$CALBACK_0.getName()方法,当调用 该方法时,Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null,如果不为空,则调用目标对象的getName 方法,如果为空,则会发起数据库查询,生成类似这样的SQL语句:select
* from user where id=’1’;来查询数据,并构造目标对象,并且将它赋值到CGLIB$CALBACK_0.target属性中。

  这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。 所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方 法才会返回实体类的代理类对象。

两种处理方法:

一、这是延时加载的问题,把有关联的所有pojo类,在hibernate.cfg.xml文件中。一般在many-to-one中,set标签内中设lazy="false" 。

二、用OpenSessionInViewFilter过滤器,注意hibernateFilter过滤器和struts2过滤器在映射时的先后顺序。同时要配置事物处理,否则会导致session处于只读状态而不能做修改、删除的动作。

在web.xml文件中加入一个filter如下:注意要加载
struts过滤器前面。

<!-- 配置opensessionInViewFilter 用于解决懒加载问题-->
	<filter>
	   <filter-name>OpenSessionInViewFilter</filter-name>
	   <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
	</filter>
<filter-mapping>
		<filter-name>OpenSessionInViewFilter</filter-name>
		<url-pattern>*.action</url-pattern>
</filter-mapping>
分析原理:

作用是拦截".action“结尾的请求,OpensessionInViewFilter的作用是将session延时关闭。

在action类中会调用service层的方法,然后调用session.一般当session访问结束之后就会将session关闭.

比如我们要得到user的列表,默认情况下是不会将其中的roles的所有信息全部查出来的,最多只给出一个id,或者是name.

但是我们这个时候如果要打印roles的类容,就会报懒加载异常了.因为hibernate根本就没有将role的数据查出来.

懒加载异常 处理方法

时间: 2024-11-05 13:50:05

懒加载异常 处理方法的相关文章

Hibernate懒加载异常说明及其解决方法

在集成ssh2三大框架的时候很容易就会造成懒加载异常,通常显示的错误信息是: org.hibernate.LazyInitializationException: could not initialize proxy - no Session 懒加载异常出现的原因: 我们在Action中调用Service中的方法,方法中开始时open session,当调用结束后close session,例如类User中有一个Department属性,我们使用Hibernate查询一个User时,hibern

Hibernate懒加载异常的解决与深刻分析

出现原因: Hibernate允许对关联对象及属性延迟加载,前提是这个操作在同一个Hibernate session范围内进行.如果发生这样的情况,当service层返回了一个启用延迟加载功能的domain对象给web层,而web层访问到这些需要延迟加载的对象或属性时,由于加载domain对象的session已经关闭导致无法访问,就会出现访问异常. 解决方法: 我们可以使用一个过滤器,在web请求时给它绑定一个Hibernatesession,这样就可以保证整个请求的过程中session都是开启

Hibernate懒加载异常解决方案总结

[什么是Hibernate懒加载异常] 我们所说的懒加载也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库,可以有效的降低数据库访问次数和内存使用量.懒加载为Hibernate中比较常用的特性之一,Hibernate 通过默认采取懒加载机制来降低系统的内存开销,提高系统性能.但这也使很多初学者使用Hibernate时容易出现懒加载异常. [出现懒加载异常的原因] 这个异常出现的原因主要是使用懒加载机制加载数据时,hibernate在从数据库

系统管理模块_部门管理_设计(映射)本模块中的所有实体并总结设计实体的技巧_懒加载异常问题_树状结构

系统管理模块_部门管理_设计本模块中的所有实体并总结设计实体的技巧 设计实体流程 1,有几个实体? 一般是一组增删改查对应一个实体. 2,实体之间有什么关系? 一般是页面引用了其他的实体时,就表示与这个实体有关联关系. 3,每个实体中都有什么属性? 1,主键.推荐使用代理主键 2,关联关系属性.在类图中,关联关系是一条线,有两端,每一端对应一个表达此关联关系的属性.有几个端指向本类,本类中就有几个关联关系属性. 3,一般属性.分析所有有关的页面,找出表单中要填写的或是在显示页面中要显示的信息等.

SpringBoot JPA懒加载异常 - com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy

问题与分析 某日忽然发现在用postman测试数据时报错如下: com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy [com.cbxsoftware.cbx.attachment.entity.RefAttachment#c109ec36e60c4a89a10eabc72416d984] - no Session (through reference chain: com.cbxsoftw

懒加载异常的解决

<filter> <!-- 平时使用懒加载时,有可能会因为hibernate的session(或着jpa的EntityManager)在事务结束时的关闭,导致页面调用数据时,出现懒加载异常 可以这样配置解决懒加载异常,让session在页面上也能使用, 但会使session打开的时间稍微长一点,并发量大时会使性能有所下降,但一般的项目没问题 --> <filter-name>OpenSessionInViewFilter</filter-name> <

SSH之懒加载异常解决方案

1.设置成即时加载 2.查询语句使用join fetch from Coupon coupon  left join fetch coupon.users  where coupon.id=:id coupon的List<users> users属性是懒加载,但是查询结果需要users的内容,则使用 left join fetch 3.使用OpenSessionInViewFilter过滤器 web.xml <!-- 以下是Spring的OpenSessionInView实现 ,唯一要求

懒加载异常 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role

@OneToMany(cascade={CascadeType.REFRESH,CascadeType.REMOVE},mappedBy="parent",fetch=FetchType.EAGER) private Set<ProductType> childTypes = new HashSet<ProductType>(); 这个是懒加载异常,就是在查询时没有加载关联表的对象,你读取这个关联对象的时候,hibernate的session已经关闭,所以无法获

iOS开发UI中懒加载的使用方法

1.懒加载基本 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其getter方法.说的通俗一点,就是在开发中,当程序中需要利用的资源时.在程序启动的时候不加载资源,只有在运行当需要一些资源时,再去加载这些资源. 我们知道iOS设备的内存有限,如果在程序在启动后就一次性加载将来会用到的所有资源,那么就有可能会耗尽iOS设备的内存.这些资源例如大量数据,图片,音频等等,所以我们在使用懒加载的时候一定要注意先判断是否已经有了,如果没有那么再去进行实例化 2.使