hibernate延迟加载与Hibernate.initialize方法

对于关联关系书本练习代码中Hibernate.initialize方法的解释:(非原创)

 

为了避免一些情况下,关联关系所带来的无谓的性能开销,Hibernate引入了延迟加载的概念。如,示例中user对象在加载的时候,会同时读取其所关联的多个地址(address)对象, 对于需要对address进行操作的应用逻辑而言,关联数据的自动加载机制的确非常有效。

但是,如果我们只是想要获得user的性别(sex)属性,而不关心user的地址(address) 信息,那么自动加载address的特性就显得多余,并且造成了极大的性能浪费。为了获得user 的性别属性,我们可能还要同时从数据库中读取数条无用的地址数据,这导致了大量无谓的系统开销。

延迟加载特性的出现,正是为了解决这个问题。所谓延迟加载,就是在需要数据的时候,才真正执行数据加载操作。

对于我们这里的user对象的加载过程,也就意味着,加载user对象时只针对其本身的属性, 而当我们需要获取user对象所关联的address信息时(如执行user.getAddresses时),才 真正从数据库中加载address数据并返回。 


尝试执行以下代码:

Criteria criteria = session.createCriteria(TUser.class); 

criteria.add(Expression.eq("name","Erica")); 
List userList = criteria.list(); 
TUser user =(TUser)userList.get(0); 

System.out.println("User name => "+user.getName()); 
Set hset = user.getAddresses(); 

session.close();//关闭Session

TAddress addr = (TAddress)hset.toArray()[0]; 
System.out.println(addr.getAddress()); 

 

运行时抛出异常: 
LazyInitializationException - Failed to lazily initialize a collection - no session or session was closed 

 

如果我们稍做调整,将session.close放在代码末尾,则不会发生这样的问题。这意味着,只有我们实际加载user 关联的address时,Hibernate 才试图通过 session从数据库中加载实际的数据集,而由于我们读取address之前已经关闭了session,所以报出session已关闭的错误。

这里有个问题,如果我们采用了延迟加载机制,但希望在一些情况下,实现非延迟加载时的功能,也就是说,我们希望在Session关闭后,依然允许操作user的addresses 属性。如,为了向View层提供数据,我们必须提供一个完整的User对象,包含其所关联的address信息,而这个User对象必须在Session关闭之后仍然可以使用。

 

Hibernate.initialize方法可以通过强制加载关联对象实现这一功能: 

Hibernate.initialize(user.getAddresses()); 
session.close(); 
//通过Hibernate.initialize方法强制读取数据 
//addresses对象即可脱离session进行操作

Set hset= user.getAddresses(); 
TAddress addr = (TAddress)hset.toArray()[0]; 
System.out.println(addr.getAddress()); 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值