OSIV会话能否初始化父实体不在会话中的代理?新请求初始化延迟集合会抛异常吗?
关于Hibernate延迟加载与OSIV的两个问题解答
基础场景回顾
当使用entityManager.find()获取包含延迟加载集合的实体时,该集合不会立即初始化,而是一个由代理包装的“占位”集合。
如果启用了Open Session in View(OSIV),会话会在整个请求周期内保持开启状态,此时只要调用集合的遍历或其他方法,就能借助活跃的会话完成集合的初始化。
问题解答
1. 若包含代理的父实体不在OSIV开启的会话中,该会话能否初始化代理?
不能。Hibernate的延迟加载代理(包括集合代理)是与创建它的原始会话强绑定的。如果父实体已经脱离了生成它的OSIV会话(比如会话已关闭、实体被序列化后跨上下文传递),即便当前有另一个OSIV会话处于开启状态,这个新会话也无法初始化该代理——代理只会尝试连接自己所属的原始会话,其他会话无法接管这个初始化操作。
2. 若保留未初始化的集合,尝试通过新请求开启的会话对其进行初始化,是否仍会抛出LazyInitializationException?
会抛出。未初始化的集合代理依然绑定在生成它的旧会话上,新请求的会话是完全独立的新上下文,和该代理没有关联。当你在新请求中尝试触发集合初始化(比如遍历集合)时,代理找不到可用的原始会话(旧会话已经随上一个请求结束而关闭),就会直接抛出LazyInitializationException。
如果想在新会话中操作该集合,需要先将父实体重新关联到新会话(比如调用entityManager.merge()),但这本质上是重新加载了实体数据,并非直接初始化原来的代理集合。
内容的提问来源于stack exchange,提问作者Kawsar Ahmed
相关产品推荐
相关产品推荐

