我有一个非常复杂的域实体。我想对所有关联进行延迟加载。所以场景是这样的:
1.获取我的业务逻辑的一个实例。
2.从业务中获取对象o。
3.要求o给我其他相关的对象。
4.准备视图。
为了在延迟加载其他对象时摆脱关闭会话的休眠异常,我想出了在控制器中打开和关闭整个会话的想法。这是个好主意吗?有没有更好的解决方案?
谢谢
我有一个非常复杂的域实体。我想对所有关联进行延迟加载。所以场景是这样的:
1.获取我的业务逻辑的一个实例。
2.从业务中获取对象o。
3.要求o给我其他相关的对象。
4.准备视图。
为了在延迟加载其他对象时摆脱关闭会话的休眠异常,我想出了在控制器中打开和关闭整个会话的想法。这是个好主意吗?有没有更好的解决方案?
谢谢
会话视图是一种不好的做法。
以下是通常用于解决此问题的层的建议:
控制器
服务
数据访问
Spring 有一个opensessioninviewfilter
和一个opensessininviewinterceptor
应该为你处理这个功能的。
作为一种设计模式,openinig session 在视图中是非常糟糕的。我认为 SpringMVC 有一个设置可以为您打开会话并解决您的问题。
但是,如果您的应用程序比宠物店更复杂,我建议不要使用这种模式。我建议将数据检索和业务逻辑下移一层,并在控制器中只保留与 UI 相关的代码。Tethinking 关系并在它们上设置急切和懒惰的设置应该有效。在没有分析的情况下将所有内容设置为惰性并不是一个好主意。每个请求都会有数百个 SQL 调用。
我建议将 L2 缓存(例如 EHCache)插入 Hibernate。配置和使用非常简单。
您确实可以做到,这是使用 Spring 和 Hibernate 时的常见模式。您可以通过将以下代码放入您的 web.xml 中轻松启用它
<filter>
<filter-name>lazyLoadingFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>lazyLoadingFilter</filter-name>
<url-pattern>/mvc/*</url-pattern>
</filter-mapping>
一旦你有了这个,在该调用中进行的每个休眠调用都将使用相同的会话:
@Autowired
protected SessionFactory sessionFactory;
protected Session getSession() {
return SessionFactoryUtils.getSession(sessionFactory, true);
}
但是,正如 Peter Gwiazda 所说,您可能希望也可能不希望这样做,具体取决于应用程序的规模和复杂性。听起来您的对象非常复杂,因此当您在 JSP 中遍历实体或任何不会导致出色性能的东西时,让您的视图本质上触发更多 SQL 语句。
通常,将对象转换为具有视图需要的 DTO 并限制从数据库取回的数据量通常是一种更好的模式。