Why is Hibernate Open Session in View considered a bad practice?

Viewed 69851

And what kind of alternative strategies do you use for avoiding LazyLoadExceptions?

I do understand that open session in view has issues with:

  • Layered applications running in different jvm's
  • Transactions are committed only at the end, and most probably you would like the results before.

But, if you know that your application is running on a single vm, why not ease your pain by using an open session in view strategy?

9 Answers

Because sending possibly uninitialised Proxies, especially collections, in the view layer and triggering hibernate loading from there can be troubling from both a performance and understanding point of view.

Understanding:

Using OSIV 'pollutes' the view layer with concerns related to the data access layer.

The view layer is not prepare to handle a HibernateException which may happen when lazy loading, but presumably the data access layer is.

Performance:

OSIV tends to tug proper entity loading under the carpet - you tend not to notice that your collections or entities are lazily initialised ( perhaps N+1 ). More convenience, less control.


Update: see The OpenSessionInView antipattern for a larger discussion regarding this subject. The author lists three important points:

  1. each lazy initialization will get you a query meaning each entity will need N + 1 queries, where N is the number of lazy associations. If your screen presents tabular data, reading Hibernate’s log is a big hint that you do not do as you should
  2. this completely defeats layered architecture, since you sully your nails with DB in the presentation layer. This is a conceptual con, so I could live with it but there is a corollary
  3. last but not least, if an exception occurs while fetching the session, it will occur during the writing of the page: you cannot present a clean error page to the user and the only thing you can do is write an error message in the body

I wouldn't say that Open Session In View is considered a bad practice; what gives you that impression?

Open-Session-In-View is a simple approach to handling sessions with Hibernate. Because it's simple, it's sometimes simplistic. If you need fine-grained control over your transactions, such as having multiple transactions in a request, Open-Session-In-View is not always a good approach.

As others have pointed out, there are some trade-offs to OSIV -- you're much more prone to the N+1 problem because you're less likely to realize what transactions you're kicking off. At the same time, it means you don't need to change your service layer to adapt to minor changes in your view.

If you're using an Inversion of Control (IoC) container such as Spring, you may want to read up on bean scoping. Essentially, I'm telling Spring to give me a Hibernate Session object whose life cycle spans the entire request (i.e., it gets created and destroyed at the start and end of the HTTP request). I don't have to worry about LazyLoadExceptions nor closing the session since the IoC container manages that for me.

As mentioned, you will have to think about N+1 SELECT performance issues. You can always configure your Hibernate entity afterwards to do eager join loading in places where performance is an issue.

The bean scoping solution is not a Spring-specific. I know PicoContainer offers the same capability and I'm sure other mature IoC containers offer something similar.

This won't help too much but you can check my topic here: * Hibernate Cache1 OutOfMemory with OpenSessionInView

I have some OutOfMemory issues because of OpenSessionInView and a lot of entities loaded, because they stay in Hibernate cache level1 and are not garbage collected (i load a lot of entities with 500 items per page, but all entities stay in cache)

Related