一.hibernate 延迟加载深入研究:
拿一对多关系来说明:
在一对多关联关系中,多的一方通过外键来关联一的一方,在查询HQL语句中,要取出多的一方与之相关联的一的一方的OID,非常容易,可在取别的属性时会遇到困难!
例如:多方: 学生po 字段值 id ,name ,oid
一方:教室 po 字段值 id ,name
取出某个学生信息:(HQL)from Student stu where stu.id=?
显示信息: System.out.println("学生姓名:"+user.getName()+"教室ID "+user.getRoom().getOid()+"教室名称"+user.getRoom().getName());
这时将会出错:could not initialize proxy - the owning Session was closed
这是因为,在hibernate 机制中默认有延迟加载lazy=”true”也就是说他只取出与只维护关系的oid,别的属性在用到时才会去,据说省内存。可在上边,当关掉 session时,他将会变为游离态也就是只有一个id属性了,别的都还没去出来。
解决办法:1.该显示信息在事务关闭之前运行。
2.取消延迟加载,在classroom.Hbm.xml中对象配置文件中直接加入lazy=”false”
3.重新将只有id 的对象,通过load() /get()方法变为持久态.
二.get() /load()根本区别
看到许多书谈论这东东感觉还不如自己想想呢:
1)查询id 对应的数据时,如果没有找到get()将会返回null,而load() 将会发生object not found异常.
2)在延迟加载 : get()返回的是一个实际的类实例. 而load()方法找到后通过代理对象去延迟加载,当真正用到数据时才会查询数据库,在使用过程中如果出现问题,将会抛异常.
User user=(User)session.load(User.class,”1”); A 返回实体对象的代理类对象
System.out.println(user.getName()); B
注:在执行到A时user因为有延迟加载加载机制,他只得到id属性,在用到别的时在从数据库去查询,,这时在A B中间来一句session.close();那就会抛出could not initialize proxy - the owning Session was closed异常的.
(转载: Hibernate并没有发起对数据的查询,如果我们此时通过一些调试工具(比如JBuilder2005的Debug工具),观察此时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 >
这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方法才会返回实体类的代理类对象。)
User user=(User)session.get(User.class,”1”); A
System.out.println(user.getName()); B
注:在用get方式时,就可以取出来了,因为他直接得到实列对象而没用延迟加载机制!
这地方选择的时候一定要慎重,是用get() 还是 load();
3)get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。”这是从别的地方听说的
三. 对于延迟加载时,用到相关联的类实例时,在session之前可以显示的给予实例化,
Classroom room=(Classroom)session.load(Classroom.class, 1);
if(!Hibernate.isInitialized(room)){
Hibernate.initialize(room);
}
这时就从代理对象类中实例化了该对象.可以在session关闭之后,取出数据.
分享到:
相关推荐
hibernate延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作!
主要介绍了Java的Hibernate框架中的缓存和延迟加载机制,Hibernate是注明的Java下SSH三大web开发框架之一,需要的朋友可以参考下
rar中包含整个项目的源码和数据库生成脚本,采用jax-ws发布Web Service服务,支持java客户端和.Net客户端调用,数据库采用oracle10g,里面有创建数据库脚本文件createTable_Oracle10g.sql,由于Hibernate映射表中会...
19.1.1. 操作延迟加载的关联 19.1.2. 调整抓取策略(Tuning fetch strategies) 19.1.3. 单端关联代理(Single-ended association proxies) 19.1.4. 实例化集合和代理(Initializing collections and proxies) ...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
16.1 Web应用程序中的Hibernate 16.1.1 用例简介 16.1.2 编写控制器 16.1.3 OSIV模式 16.1.4 设计巧妙的领域模型 16.2 创建持久层 16.2.1 泛型的数据访问对象模式 16.2.2 实现泛型...
19.1.1. 操作延迟加载的关联 19.1.2. 调整抓取策略(Tuning fetch strategies) 19.1.3. 单端关联代理(Single-ended association proxies) 19.1.4. 实例化集合和代理(Initializing collections and proxies) ...
19.1.1. 操作延迟加载的关联 19.1.2. 调整抓取策略(Tuning fetch strategies) 19.1.3. 单端关联代理(Single-ended association proxies) 19.1.4. 实例化集合和代理(Initializing collections and proxies) ...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
提供了EclipseLink和Hibernate持久性提供程序的JPA延迟加载。 具有JPA持久层和Spring MVC Web层的双层应用程序。 可以用Maven构建,下载后mvn jetty:run命令mvn jetty:run 。 它默认设置为 EclipseLink,您需要...
Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。 Spring3.0引入了众多Java开发者翘首以盼的新功能...附录B 在Spring中开发Web Service
Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。 Spring3.0引入了众多Java开发者翘首以盼的新功能...附录B 在Spring中开发Web Service
目录 前言 1.... 2.... 1. 在Tomcat中快速上手 ... 1.1. 开始Hibernate之旅 ... 操作延迟加载的关联 20.1.2. 调整抓取策略(Tuning fetch strategies) 20.1.3. 单端关联代理(Single-ended association proxies) ...
19.1.1. 操作延迟加载的关联 19.1.2. 调整抓取策略(Tuning fetch strategies) 19.1.3. 单端关联代理(Single-ended association proxies) 19.1.4. 实例化集合和代理(Initializing collections and proxies) ...
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。 3.Hibernate中怎样实现类之间的...
5.3.4 立即加载和延迟加载 5.3.4 悲观锁和乐观锁 5.4 GORM查询 5.4.1 动态查找器 5.4.2 条件查询 5.4.3 Hibernate查询语言 5.5 高级GORM特性 5.5.1 事件和自动实现时间戳 5.5.2 自定义ORM映射 5.5.2.1 表名和列名 ...
97、Hibernate是如何延迟加载? 22 98、Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 22 99、说下Hibernate的缓存机制 22 100、Hibernate的查询方式 23 101、如何优化Hibernate? 23 102、Struts工作...