tags:

views:

4228

answers:

7

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?

+1  A: 

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
Robert Munteanu
Ok, it 'pollutes' the view layer with hibernate exception. But, regarding performance, i think the problem is quite similar than to access a service layer that will return your dto. If you face a performance problem, then you should optimize that specific issue with a smarter query or a more lightweight dto.If you have to develop too many service methods to handle possibilities you could need in the view, you are also 'polluting' the service layer. no?
HeDinges
One difference is that it delays the closing of the Hibernate session. You will wait for the JSP to be rendered/written/etc, and that keeps the objects in memory longer. That may be a problem especially if you need to write data on session commit.
Robert Munteanu
It doesn't make sense to say that OSIV hurts Performance. What alternatives are there except for using DTOs? In that case, you will *always* have lower performance because data used by any view will have to be loaded even for views that don't need it.
Johannes Brodwall
I think the pollution works the other way round. If I need to eager load the data, the logic layer (or worse the data access layer) need to know in which way an object is going to be displayed. Change the view and you end up loading stuff you don't need or missing objects you need. A Hibernate Exception is a bug and just as poisoning as any other unexpected exception.But performance is an issue. Performance and scalability issues will force you to put more thought and work in your data access layer, and possibly force the session to be closed earlier
Jens Schauder
+2  A: 

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.

0sumgain
+2  A: 

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.

Geoffrey Wiseman
A: 

I am v. rusty on Hibernate.. but I think its possible to have multiple transactions in one Hibernate session. So your transaction boundaries do not have to be the same as session start/stop events.

OSIV, imo, primarily is useful because we can avoid writing code for starting a 'persistence context' (a.k.a. session) every time the request needs to make a DB access.

In your service layer, you will probably need to make calls to methods which have different transaction needs, such as 'Required, New Required, etc.' The only thing these methods need is that somebody (i.e the OSIV filter) has started up the persistence context, so that only thing they have to worry about is - "hey give me the hibernate session for this thread.. I need to do some DB stuff".

rjk2008
A: 

I just did a post on some guidelines as to when to use open session in view in my blog. Check it out if your interested.

http://heapdump.wordpress.com/2010/04/04/should-i-use-open-session-in-view/

Chris Upton
A: 
  • transactions can be committed in the service layer - transactions are not related to OSIV. It's the Session that stays open, not a transaction - running.

  • if your application layers are spread across multiple machines, then you pretty much can't use OSIV - you have to initialize everything you need before sending the object over the wire.

  • OSIV is a nice and transparent (i.e. - none of your code is aware that it happens) way to make use of the performance benefits of lazy loading

Bozho
Regarding the first bullet point, this is at least not true for the original [OSIV](http://community.jboss.org/wiki/OpenSessioninView) from the JBoss wiki, it also handles transaction demarcation around the request.
Pascal Thivent
A: 

In my own experience, OSIV is not so bad. The only arrangement I made is using two different transactions: - the first, opened in "service layer", where I have the "business logic" - the second opened just before the view rendering

Davide