hibernate的延迟加载

标签: hibernate 延迟加载 | 发表时间:2012-12-29 00:16 | 作者:
出处:http://www.iteye.com
[size=large]

    先看一段代码:

public class LazyLoadTest {
    @Test
    public void showLazyLoad(){
        Session session=HibernateUtil.getSession();
       
        Major major=(Major) session.load(Major.class, 1);
        session.close();
        
        //print the name of this major
        System.out.println(major.getName());
    }
}

    代码的逻辑是:查询出id为1的major, 并输出其名字. 很明显, 代码的逻辑是对的.   可一运行就会报错:

引用

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

 
翻译过来就是:  延迟加载异常:不能初始化代理 --- session不存在. 出现这个报错信息的原因就在于hibernate的延迟加载机制.

    所谓的延迟加载就是程序在使用load, iterator方法执行查询及关联查询时, 并不会马上发送并执行sql语句, 而是在调用(被查询)对象属性的getter方法时才去执行查询.
所以若将代码改为:

     Major major=(Major) session.load(Major.class, 1);
     major.getName();
     session.close();
     System.out.println(major.getName());

则能正常运行
   可这样做了无用功, 因为major.getName()方法的调用没有体现出任何业务逻辑.应通过使用不同的方法来避免延迟加载.如:

     Major major=(Major) session.get(Major.class, 1);
     session.close();
     System.out.println(major.getName());

将load方法替换为get方法后程序也能正常运行.

    hibernate延迟加载机制是默认开启的, 但只在三种情况下出现延迟加载:使用session的load方法, query的iterator方法进行查询及关联查询时.  相应的避免方法为:
    session.load--->session.get
    query.iterator---> query.list
    关联查询:有两种方法:a.修改配置文件:在映射文件中给关联映射元素添加fetch='join'属性; b.在hql语句中使用join fetch 关键字. a不如b灵活, 建议使用b.

    还有一个小小的陷阱:

     Major major=(Major) session.load(Major.class, 1);
     major.getId();
     session.close();
     System.out.println(major.getName());


猜猜看这段代码是否能正常运行? 用load方法将major查询出来后调用其id属性的get方法, 照理说应该能正常运行, 但结果却会报错, 错误信息和第一段代码一样.
这又是什么原因呢? 原来在使用load方法时, major对象的id属性已经给出了, 在调用其id的get方法时不需要执行查询操作.所以major.getId();这句代码有和没有是一个样, 程序都不会去执行真正的查询操作.

上面这些现象也许会让人觉得它的存在纯粹是一个麻烦精, 可事实是延迟加载的好处是大大的有: 它可以降低数据库访问的并发率, 还可以极大的提高关联查询的效率, 因为它使程序在查询数据时可以做到用到时才查, 不用时不查, 减少了不必要的内存开销.
所以hibernate延迟加载机制的存在有理由,有好处,也有坏处. 在使用时只要注意不过早关闭session,就会发现它还是挺好用的.

(数据库表格见http://keepcrazy.iteye.com/blog/1753444的附件)
[/size]

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [hibernate 延迟加载] 推荐:

hibernate的延迟加载

- - ITeye博客
    代码的逻辑是:查询出id为1的major, 并输出其名字. 很明显, 代码的逻辑是对的.   可一运行就会报错:. 翻译过来就是:  延迟加载异常:不能初始化代理 --- session不存在. 出现这个报错信息的原因就在于hibernate的延迟加载机制.     所谓的延迟加载就是程序在使用load, iterator方法执行查询及关联查询时, 并不会马上发送并执行sql语句, 而是在调用(被查询)对象属性的getter方法时才去执行查询.

Hibernate延迟加载机制

- - 企业架构 - ITeye博客
转自:http://blog.163.com/xi_zh_qi/blog/static/8501594200812695053939/.    延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作. 在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载.

Mybatis查询延迟加载

- - Elim的个人空间
Mybatis 查询延迟加载. 1.1        启用延迟加载. 1.2        分析.        Mybatis的延迟加载是针对嵌套查询而言的,是指在进行查询的时候先只查询最外层的SQL,对于内层SQL将在需要使用的时候才查询出来. Mybatis的延迟加载默认是关闭的,即默认是一次就将所有的嵌套SQL一并查了将对象所有的信息都查询出来.

背景图延迟加载(lazyload)技术

- - Web骇客
图片延迟加载技术目前已经被各种网站广泛的使用,但最近的一篇《 PS美女试验的惊人结果 》文章中使用的却是背景图延迟加载技术. 为什么要使用背景图延迟加载技术. 之所以使用图片延迟加载技术,是为了避免浪费带宽. 有些页面上嵌入了很多图片(上面所说的《 PS美女试验的惊人结果 》里就嵌入了30多张高清美女图),但电脑的屏幕一次只能显示一张或顶多2张.

拒绝图片延迟加载,爽爽的看美图

- 书皮 - 博客园-首页原创精华区
    有一天我一个朋友访问一个XX图片网站……每个人背后总有几个背黑锅的“朋友”,好吧,我承认那个“朋友”其实是我自己,你能把我怎么的.     这个网站用的是Discuz X2搭建的,启动了Discuz的图片延迟加载的功能. 现在很多图片网站为了降低服务器压力都启用了图片延迟加载的机制,也就是只有图片处于可视区域才加载,这样用户没看到的图片就不加载,对于服务器的负载减轻还是帮助很大的.

延迟加载图片的 jQuery 插件:Lazy Load

- - 我爱水煮鱼
网站的速度非常重要,现在有很多网站优化的工具,如 Google 的 Page Speed,Yahoo 的 YSlow,对于网页图片,Yahoo 还提供 Smush.it 这个工具对图片进行批量压缩,但是对于图片非常多的网站,载入网页还是需要比较长的时间,这个时候我们可以使用 Lazy Load 这个 jQuery 插件来延迟加载图片.

图片延迟加载 - 前端开发技能必备系列

- - 博客园_首页
在网上经常会看到一些很长的网页会延迟加载其中的图片,我认为这是一种按需分配的做法,网页只为那些想继续浏览网页的人加载后面的图片,在不影响用户体验的前提下,最大程度地减少服务器负担和流量. 目前,主要的购物网站都采用了这种加载方式. 今天在一个网友的站里发现一个图片延迟加载的插件,很好用,在这里介绍一下.

一款非常轻量的延迟加载插件

- - CSS库
jQuery Unveil 是一款轻量的延迟加载插件,支持提供用于视网膜显示设备的高分辨率图像. 这个插件非常有用,它能提高长网页中图像的加载性能,因为视口以外的图像(可见部分网页)将不会被加载,直到用户滚动到它们所在的区域.   延迟加载有一些很酷的选项,如自定义效果,容器,事件或数据属性. 如果你不想使用这些功能,你可以减小文件的大小,只留下必要的代码来显示图像.

Hibernate面试题

- - ITeye博客
什么是Hibernate的并发机制. Hibernate并发机制:. a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次,. 如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用.

Hibernate Lazy属性

- - 博客园_首页
  Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术. 这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录. 通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销. Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势.