Seconding Joe: Use OpenSessionInViewInterceptor when working with Spring's DispatcherServlet, and OpenSessionInViewFilter when working with a different web framework. Both will reuse the same Session across an entire request, automatically letting Spring-managed transactions work with that Session - the business layer does not have to change. As the Session will be open during view rendering, lazy loading will work then.
OpenSessionInViewInterceptor can be registered with a Spring HandlerMapping, via the "interceptors" property. If you just want to apply it to a selection of your controllers, simply split your handler mappings into two: one for all controllers with OpenSessionInViewInterceptor, one for the rest. A Spring DispatcherServlet can work with any number of HandlerMappings (typically explicit SimpleUrlHandlerMappings here).
Note that there can be side effects when applying OpenSessionInViewInterceptor to existing business-level transactions: Without the interceptor, each transaction uses its own Session; with the interceptor, all transactions within a single web request share the same Session. For example:
- You might want to reassociate objects via Session.update: Equal instances must not be loaded in the Session before. But other code has executed on the same Session before here, potentially having loaded such equal instances.
- You might rely on being able to modify a Hibernate-loaded object without persisting the changes, after the transaction that loaded it has finished. This does not apply if further transactions are executed on the same Session - they will flush those changes!
Actually, Spring's "Open Session in View" support is pretty new (1.0 M4), so the question hasn't been asked to death yet ;-) There have been quite a few feature requests in that direction before, though. BTW, Atlassian are using Spring's OpenSessionInViewFilter with WebWork2 on a Spring middle tier in their new product Confluence.
Juergen
|