教你如何在Hibernate中实例化集合和代理

开发 后端
Hibernate实例化集合和代理在Session范围之外访问未初始化的集合或代理,Hibernate将会抛出LazyInitializationException异常。

本文向大家介绍Hibernate中实例化集合和代理,可能好多人还不了解Hibernate中实例化集合和代理,没有关系,看完本文你肯定有不少收获,希望本文能教会你更多东西。

Hibernate中实例化集合和代理在Session范围之外访问未初始化的集合或代理,Hibernate将会抛出LazyInitializationException异常。 也就是说,在分离状态下,访问一个实体所拥有的集合,或者访问其指向代理的属性时,会引发此异常。

有时候我们需要保证某个代理或者集合在Session关闭前就已经被初始化了。 当然,我们可以通过强行调用cat.getSex()或者cat.getKittens().size()之类的方法来确保这一点。 但是这样的程序会造成读者的疑惑,也不符合通常的代码规范。

静态方法Hibernate.initialized() 为你的应用程序提供了一个便捷的途径来延迟加载集合或代理。 只要它的Session处于open状态,Hibernate.initialize(cat) 将会为cat强制对代理实例化。 同样,Hibernate.initialize( cat.getKittens() ) 对kittens的集合具有同样的功能。

还有另外一种选择,就是保持Session一直处于open状态,直到所有需要的集合或代理都被载入。 在某些应用架构中,特别是对于那些使用Hibernate进行数据访问的代码,以及那些在不同应用层和不同物理进程中使用Hibernate的代码。 在集合实例化时,如何保证Session处于open状态经常会是一个问题。有两种方法可以解决此问题:

在一个基于Web的应用中,可以利用servlet过滤器(filter),在用户请求(request)结束、页面生成 结束时关闭Session(这里使用了在展示层保持打开Session模式(Open Session in View)), 当然,这将依赖于应用框架中异常需要被正确的处理。

在返回界面给用户之前,乃至在生成界面过程中发生异常的情况下, 正确关闭Session和结束事务将是非常重要的, 请参见Hibernate wiki上的"Open Session in View"模式,你可以找到示例。

在一个拥有单独业务层的应用中,业务层必须在返回之前,为web层“准备”好其所需的数据集合。这就意味着 业务层应该载入所有表现层/web层所需的数据,并将这些已实例化完毕的数据返回。

通常,应用程序应该 为web层所需的每个集合调用Hibernate.initialize()(这个调用必须发生咱session关闭之前); 或者使用带有FETCH从句,或FetchMode.JOIN的Hibernate查询, 事先取得所有的数据集合。

如果你在应用中使用了Command模式,代替Session Facade , 那么这项任务将会变得简单的多。

你也可以通过merge()或lock()方法,在访问未实例化的集合(或代理)之前, 为先前载入的对象绑定一个新的Session。

显然,Hibernate将不会,也不应该自动完成这些任务,因为这将引入一个特殊的事务语义。

有时候,你并不需要完全实例化整个大的集合,仅需要了解它的部分信息(例如其大小)、或者集合的部分内容。

你可以使用集合过滤器得到其集合的大小,而不必实例化整个集合:

  1. ( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue() 

这里的createFilter()方法也可以被用来有效的抓取集合的部分内容,而无需实例化整个集合:

  1. s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list(); 

【编辑推荐】

  1. 对Hibernate一级缓存与二级缓存的解析
  2. Hibernate传播性持久化攻略
  3. 深入了解Hibernate自动状态检测
  4. 简单学会Hibernate对象持久化
  5. 分析Hibernate自增主键
责任编辑:仲衡 来源: 博客园
相关推荐

2009-09-23 13:04:58

HibernateOracle sequ

2009-09-25 11:14:16

Hibernate批量

2009-07-28 08:39:56

Linux应用软件Linux应用

2009-09-23 08:56:18

Hibernate cHibernate i

2022-04-27 08:55:01

Spring外部化配置

2011-08-10 09:31:41

Hibernateunion

2009-09-23 17:05:52

Hibernate S

2010-07-02 10:18:23

ucd-snmpMIB

2009-09-25 16:57:49

Hibernate查询

2014-12-16 12:54:09

BIOS虚拟化技术

2009-09-23 10:14:22

Hibernate

2009-09-27 16:21:22

Hibernate C

2021-08-31 08:01:40

STM32DSP指令

2022-04-22 09:20:06

FreeBSD 13MySQL数据库

2011-08-31 13:08:31

winXPwin7创建还原点

2012-02-03 11:17:33

HibernateJava

2020-12-15 09:26:20

LinuxVLAN命令

2023-09-21 10:46:42

CIOCMO

2021-04-04 22:56:47

Linux循环用户

2022-11-28 08:23:14

IDEAGradle配置
点赞
收藏

51CTO技术栈公众号