简体   繁体   English

在MVC体系结构的控制器中打开休眠会话是个好主意吗?

[英]Is it a good idea to open a hibernate session in controller in MVC architecture?

I have a pretty complex domain entities. 我有一个非常复杂的域实体。 I want to have lazy loading for all of associations. 我想对所有关联进行延迟加载。 So the scenario is like this: 所以场景是这样的:

1.get an instance of my business logic. 1.获取我的业务逻辑实例。

2.get an object o from business. 2.从业务中获取对象。

3.ask o to give me other associated objects. 3.问o给我其他相关对象。

4.prepare the view. 4.准备视图。

To get rid of hibernate exceptions about closed session when lazy load other objects, I've come up to the idea to open and close entire session in controller. 为了摆脱在延迟加载其他对象时关闭会话的休眠异常,我想到了在控制器中打开和关闭整个会话的想法。 Is it a good idea? 这是个好主意吗? Are there any better solutions? 有更好的解决方案吗?

Thank you 谢谢

Session in view is a bad practice . 鉴于会议是一种不良做法

Here is a suggestion for layers which are typically used to work around this problem: 这是通常用于解决此问题的层的建议:

Controller 控制者

  • The controller is only concerned with handling web requests, interpreting them into objects that your services will deal with, and returning services results as web responses. 控制器仅关心处理Web请求,将其解释为服务将要处理的对象以及将服务结果作为Web响应返回。 I usually have only one transactional service method call in each controller method, preferring to keep all data access for one controller operation within a single transaction. 我通常在每个控制器方法中只有一个事务服务方法调用,更喜欢在一个事务中将一个控制器操作的所有数据访问都保留下来。

Service 服务

  • The service layer is only concerned with accepting data from controller, obtaining the data it needs (from data layer) to perform its operations, and returning meaningful results. 服务层只关心从控制器接收数据,从中获取执行操作所需的数据(从数据层),并返回有意义的结果。 The service should fully load all lazy-loaded entities required by the controller. 该服务应完全加载控制器所需的所有延迟加载的实体。 The service methods here are transactional and won't have lazy loading issues, and you can assemble results from multiple DAO's. 这里的服务方法是事务性的,不会出现延迟加载问题,您可以组合多个DAO的结果。 That way DAO's don't need to know about each other . 这样,DAO无需彼此了解

Data Access 资料存取

  • The data access layer is only concerned with persistence (CRUD), allowing access to data with filtering, ordering, and so on. 数据访问层仅与持久性(CRUD)有关,它允许通过过滤,排序等方式访问数据。

Spring有一个opensessioninviewfilter和一个opensessininviewinterceptor ,它们应该为您处理此功能。

As a design pattern openinig session in view is very bad. 作为一种设计模式,openinig会话的观点非常糟糕。 I think that SpringMVC has a setting that causes opening session for you and solves your problem. 我认为SpringMVC的设置会导致您打开会话并解决您的问题。

However I'd suggest not using this pattern if your application is more complex than a pet store. 但是,如果您的应用程序比宠物商店复杂,我建议不要使用此模式。 I'd suggest moving data retrieval and business logic one layer down and leave only UI-related code in controllers. 我建议将数据检索和业务逻辑向下移动一层,并在控制器中仅保留与UI相关的代码。 Tethinking relations and setting eager and lazy settings on them should work. 认真思考关系并对其设置急切和懒惰的设置应该有效。 Setting everything to lazy without analysis is not a good idea. 不进行分析而将所有内容设置为惰性不是一个好主意。 It'll end up in hundreds of SQL calls per request. 每个请求最终将进行数百次SQL调用。

I'd suggest plugging L2 cache (eg EHCache) to Hibernate. 我建议将L2缓存(例如EHCache)插入Hibernate。 Configuration and usage is really easy. 配置和使用非常简单。

You can indeed do it and it is a common pattern when using Spring and Hibernate. 您确实可以做到,这是使用Spring和Hibernate时的常见模式。 You can enable it very easily by putting the code below in your web.xml 通过将下面的代码放入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>

Once the you have this in place, every call in hibernate made within that call will use the same session: 一旦设置好位置,该调用中在休眠状态下进行的每个调用都将使用相同的会话:

@Autowired
protected SessionFactory sessionFactory;

protected Session getSession() {

    return SessionFactoryUtils.getSession(sessionFactory, true);
}

However, as Peter Gwiazda says, you may or may not want to do this depending on the scale and complexity of your application. 但是,正如Peter Gwiazda所说,您可能会或可能不想这样做,具体取决于应用程序的规模和复杂性。 It sounds like your objects are quite complex so having your views essentially trigger more SQL statements as you traverse your entity in your JSP or whatever is not going to lead to great performance. 听起来您的对象很复杂,所以当您在JSP中遍历实体时,让视图本质上会触发更多的SQL语句,或者任何不会带来出色性能的事情。

It is generally a better pattern to convert your object into a DTO with just what your view needs and limit the amount of data you fetch back from your database. 通常,将视图满足需求的对象转换为DTO并限制从数据库中取回的数据量通常是更好的模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM