Hibernate 为什么不使用Spring';s OpenEntityManager视图过滤器
虽然很多帖子都是关于Spring的OpenSession/EntityManagerInViewFilter的,但我找不到任何提到它的缺陷的帖子。据我所知,并假设使用@Transactional服务层的典型分层web应用程序体系结构,过滤器的工作原理如下:Hibernate 为什么不使用Spring';s OpenEntityManager视图过滤器,hibernate,spring,lazy-loading,Hibernate,Spring,Lazy Loading,虽然很多帖子都是关于Spring的OpenSession/EntityManagerInViewFilter的,但我找不到任何提到它的缺陷的帖子。据我所知,并假设使用@Transactional服务层的典型分层web应用程序体系结构,过滤器的工作原理如下: 过滤器拦截servlet请求 过滤器打开EntityManager并将其绑定到当前线程 Web控制器被称为 Web控制器调用服务 事务拦截器开始一个新事务,检索线程绑定的EntityManager并将其绑定到事务 调用服务,使用EntityM
谢谢 正如您所说,OpenSessionInView过滤器在web应用程序中非常方便。关于你提到的限制: 1) 加载多个惰性关联将导致多个数据库事务,这可能会影响性能 是的,经常访问数据库可能会导致性能问题。理想情况下,您希望在一次旅行中获取所需的所有数据。考虑为此使用Hibernate连接获取。但是从数据库获取太多数据也会很慢。我使用的经验法则是,如果每次绘制视图时都需要数据,则使用连接获取;如果在大多数情况下不需要数据,我会让Hibernate lazy在需要时获取数据——threadlocal open会话会有帮助 2) 根对象及其惰性关联加载在不同的数据库事务中,因此数据可能已过时(例如,由线程1加载的根、由线程2更新的根关联、由线程1加载的根关联) 想象一下用JDBC编写这个应用程序——如果应用程序的一致性要求根和叶都应该加载到同一个txn中,那么就使用连接抓取。如果不是,通常情况下,延迟抓取不会导致任何一致性问题
我想,OpenSessionInView更重要的缺点是当您希望在非web上下文中重用服务层时。根据您的描述,您似乎没有这个问题。我听到的反对OpenSessionInView和延迟加载的主要论点是事务过多,对性能有负面影响。在低使用要求的应用程序上使用非常方便,但在高规模应用程序上,我建议使用老式的完全填充DTO(数据传输对象)。我在OpenSessionInViewFilter中遇到的主要问题之一是使用AJAX应用程序和javascript。如果您使用javascript呈现网格或某些UI组件;有一个延迟负载(考虑到你打开了过滤器);然后抛出一个异常。您的应用程序UI呈现将面临挑战。数据可能永远不会显示,页面开始抛出奇怪的javascript异常,您需要编写额外的js代码来处理这些异常。而且您正在向用户公开数据库异常(这不是一个好主意)
在常规应用程序中,可以捕获这些异常并抛出有效的用户异常 如果您的应用程序是一个多层体系结构(部署在不同JVM上的视图层和部署在不同VM上的服务层),那么将会话保持在打开状态是没有意义的。如果您的服务层独立于您的应用程序层,我将看到不使用任何OpenSessionViewFilter