除了使用 OpenSessionInView 模式之外,还有其他方法可以避免 Hibernate Web 应用程序中的 LazyInitializationExceptions 吗?使用 OpenSessionInView 有什么缺点吗?
4 回答
在处理我们的 Web 应用程序时,我们通常会事先决定视图页面中需要哪些对象/字段,并确保在分派到视图之前从模型正确初始化所有对象。
这可以通过(至少)三种方式实现:
- 使用 Eager 策略获取属性(即
FetchMode.JOIN
,如果您使用Criteria API ,则使用) - 显式初始化属性(即使用
Hibernate.initialize(property)
) - 通过调用适当的属性访问器隐式初始化属性
关于 OpenSessionInView 的缺点,你查看过这个页面吗?
通常是处理问题的最佳方式,无需做出全局决定来进行急切获取;就是将“fetch”关键字与 hql 查询结合使用。
来自http://www.hibernate.org/hib_docs/reference/en/html/queryhql-joins.html
此外,“获取”连接允许使用单个选择来初始化值的关联或集合及其父对象。这在集合的情况下特别有用。它有效地覆盖了关联和集合的映射文件的外部连接和惰性声明。有关详细信息,请参阅第 19.1 节,“获取策略”。
from Cat as cat inner join fetch cat.mate left join fetch cat.kittens
切换到 JBoss Seam。
Seam 框架由开发 Hibernate 的人精心设计。
即使使用 View 中的 Open Session,您仍可能遇到一些问题。根据您的 Web 应用程序的复杂程度,Open Session In View 并不能处理所有情况。在石英作业(例如发送电子邮件)期间,我在显示数据以及(在 UI 中)获取实体时遇到了问题。
Hibernate 已经智能地抓取数据,改变抓取模式会导致性能下降。不仅如此,您还摆脱了惯例,并且会用无关的配置细节弄乱您的项目。
沃尔特
The Oracle Java tutorials point out that "Enterprise beans support transactions, the mechanisms that manage the concurrent access of shared objects." So, in order to handle the Lazy Fetch issues I create a Stateless Java Session Bean and then get all of the sub classes I need before returning from the method. Oracle has also referred to this as a "Session Façade" core J2EE pattern. These practices seem like much better application practices than some of the other ones mentioned.