views:

1782

answers:

2

Hi, I'm thinking about using the Open Session In View (OSIV) filter or interceptor that comes with Spring, as it seems like a convenient way for me as a developer. If that's what you recommend, do you recommend using a filter or an interceptor and why?

I'm also wondering how it will mix with HibernateTemplate and if I will lose the ability to mark methods as @Transactional(readOnly = true) etc and thus lose the ability to get some more fine grained transaction control?

Is there some kind of best practice for how to integrate this kind of solution with a three tier architecture using Hibernate and Spring (as I suppose my decision to use Wicket for presentation shouldn't matter much)?

If I use OSIV I will at least never run into lazy loading exceptions, on the other hand my transaction will live longer before being able to commit by being uncommitted in the view as well.

+1  A: 

If I use OSIV I will at least never run into lazy loading exceptions

that is not true, in fact its extremely easy to run into the infamous LazyInitializationException, just load an object, and try to read an attribute of it, after the view, depending on your configuration you WILL get the LIE

Michael Lange
Down vote with no comment? At least explain why. If what the poster said is incorrect, perhaps we can all learn from the explanation.
duffymo
I'll down vote it too, with a comment.As far as I understand if you have a session and are inside a transaction in the presentation layer, you will never get lazy initiation exception.And "after the view" will never happen, as it's the last thing happening.I need a better explanation for an up-vote.
DeletedAccount
the problem is not OSIV itself, but hibernatewith OSIV you still can't "automagically" re-attach a previously loaded object to a new session, for me this is one of the most problems witch leads to the LIE
Michael Lange
You request entities from the business layer.You have them and may access any attribute until the view ends.At that point you don't throw away the entity,you keep it some how (serialize it maybe),then you try accessing something and boom? My -1 ==back=to=> 0 as it's still not a solution proposal.
DeletedAccount
If you persist your Hibernate entities across requests (e.g. in the session) you have a major architecture problem. So yes, it is possible to get LIE even with OSIV, but if you do, you asked for it !
Guillaume
Guillaume: For example Wicket stores it's models in the session between calls. In the models you have view related data, like entities to display. Wicket is quite popular and I don't think its users feel they have a major architecural problem by using it. So it's a matter of opinion. :-)
DeletedAccount
+4  A: 

It's really a matter of personal taste.

Personally, I like to have transaction boundaries at the service layer. If you start thinking SOA, every call to a service should be independent. If your view layer has to call 2 different services (we could argue that this is already a code smell) then those 2 services should behave independently of each other, could have different transaction configurations, etc... Having no transactions open outside of the services also helps make sure that no modification occurs outside of a service.

OTOH you will have to think a bit more about what you do in your services (lazy loading, grouping functionalities in the same service method if they need a common transactionality, etc ...).

One pattern that can help reduce lazy-loading error is to use Value Object outside of the service layer. The services should always load all the data needed and copy it to VOs. You lose the direct mapping between your persistent objects and your view layer (meaning you have to write more code), but you might find that you gain in clarity ...

Edit: The decision will be based on trade offs, so I still think it is at least partly a matter of personal taste. Transaction at the service layer feels cleaner to me (more SOA-like, the logic is clearly restrained to the service layer, different calls are clearly separated, ...). The problem with that approach is LazyLoadingExceptions, which can be resolved by using VO. If VO are just a copy of your persistent objects, then yes, it is clearly a break of the DRY principle. If you use VO like you would use a database View, then VO are a simplification of you persistent objects. It will still be more code to write, but it will make your design clearer. It becomes especially useful if you need to plug some authorization scheme : if certain fields are visible only to certain roles, you can put the authorization at the service level and never return data that should not be viewed.

Guillaume
It's not just a matter of personal taste,it changes how you do things which changes performance and how easy the code will be to maintain and work with.More boiler-plate code, more code maintainability head aches.Using VO's sounds dirty with lots of very similar code, sounds a bit like breaking DRY.
DeletedAccount
That said, VO's do allow me to have granular control of transactions in the business layer (using @Transactional), the transactions will have a shorter life span (a bit more scalable) and crystal clear separation between business and presentation layer.
DeletedAccount