0

我有一个非常复杂的域实体。我想对所有关联进行延迟加载。所以场景是这样的:

1.获取我的业务逻辑的一个实例。

2.从业务中获取对象o。

3.要求o给我其他相关的对象。

4.准备视图。

为了在延迟加载其他对象时摆脱关闭会话的休眠异常,我想出了在控制器中打开和关闭整个会话的想法。这是个好主意吗?有没有更好的解决方案?

谢谢

4

4 回答 4

1

会话视图是一种不好的做法

以下是通常用于解决此问题的层的建议:

控制器

  • 控制器只关心处理 Web 请求,将它们解释为您的服务将处理的对象,并将服务结果作为 Web 响应返回。我通常在每个控制器方法中只有一个事务服务方法调用,更愿意在单个事务中保留一个控制器操作的所有数据访问。

服务

  • 服务层只关心从控制器接受数据,获取它需要的数据(从数据层)来执行它的操作,并返回有意义的结果。该服务应完全加载控制器所需的所有延迟加载实体。这里的服务方法是事务性的,不会有延迟加载问题,并且您可以从多个 DAO 组装结果。这样 DAO 就不需要互相了解了

数据访问

  • 数据访问层只关心持久性(CRUD),允许通过过滤、排序等访问数据。
于 2012-07-27T17:44:25.907 回答
0

Spring 有一个opensessioninviewfilter和一个opensessininviewinterceptor应该为你处理这个功能的。

于 2012-07-27T10:51:00.613 回答
0

作为一种设计模式,openinig session 在视图中是非常糟糕的。我认为 SpringMVC 有一个设置可以为您打开会话并解决您的问题。

但是,如果您的应用程序比宠物店更复杂,我建议不要使用这种模式。我建议将数据检索和业务逻辑下移一层,并在控制器中只保留与 UI 相关的代码。Tethinking 关系并在它们上设置急切和懒惰的设置应该有效。在没有分析的情况下将所有内容设置为惰性并不是一个好主意。每个请求都会有数百个 SQL 调用。

我建议将 L2 缓存(例如 EHCache)插入 Hibernate。配置和使用非常简单。

于 2012-07-27T10:53:22.400 回答
0

您确实可以做到,这是使用 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 并限制从数据库取回的数据量通常是一种更好的模式。

于 2012-07-27T11:14:14.090 回答