[Hibernate] Open Session in View Pattern
I get this question a lot when folks check out my struts-resume application - so I figured I'd document it here - and then I can just send future developers a URL. The question is this:
Why do you tie your View to your Model Implementation by putting a Hibernate Session in your Service Interfaces?
I have a couple of reasons. The first reason is that I initially had ses.currentSession()
and ses.closeSession()
at the beginning and end of each DAO
method. In fact, I found this old
e-mail where you can see an example. This seemed to work for me and
I was happy with it. However, I got an e-mail from Gavin
(Hibernate's Lead Developer) that I was doing it all wrong. He said that I
should use one session per request, rather than one on each method. Why? For
performance reasons and to allow rolling back the entire session, rather
than just a method. At least that's why I remember him saying.
So I refactored and implemented the Open Session in View pattern
in conjunction with the Thread Local Session. You
can checkout my ActionFilter and ServiceLocator for the View and
ThreadLocal, respectively.
The problem now is that I pass my the Session object from my View ->
Business Layer [example: UserManager]
-> DAO Layer. So I'm tightly coupled with Hibernate, which I don't mind,
because I really, really like Hibernate and have no plans to
implement an alternate DAO (even though the architecture allows it). Even
if I did choose to implement a new plain ol' JDBC DAO Layer, I can always
get a java.sql.Connection
from the Session using
ses.connection()
. Another option I've thought of is to just
pass the ServiceLocator between the different layers, and call
ses.currentSession()
or ses.connection()
when it's
needed. But that seems to be the same thing I was doing before when I was
opening/closing at the method level.
Comments and suggestions, as always,
are welcomed and encouraged.
Posted by Jason Boutwell on June 11, 2003 at 08:47 PM MDT #
Posted by Adam Sherman on June 11, 2003 at 09:54 PM MDT #
Well, that much I did realize :) (I like Hibernate a lot too), so I guess the only question left is - since you are instantiating the UserManagerImpl in the Business Delegates (e.g. UserManager) in Struts-Resume, why can't you just make a UserManagerImpl(Session s) constructor, rather than desecrating the interface API, and tying it to the interface API signature. I think that's a helluva lot cleaner :). And inside the Impl class, have a private instance Session var to which you will assign the Session and use it for the entire transaction. Or have a JDBC "Connection" constructor, and just pass in a connection if you're a JDBC junkie and you can afford to handcode JDBC for your project... Makes more sense, no? :) So your UserManager interface becomes:
And then for each type of UserManagerImpl, you'd have a constructor like:
And then for a JDBC based UserManagerImpl, you'd have
Now everyone's happy because they can use either a Hibernate implementation or handcoded JDBC implementation (or EJB, if you're really perverted ;), and the interface API signatures are clean, that is, not tied to any particular persistence layer.
:)
Martin
Posted by Martin Naskovski on June 11, 2003 at 10:03 PM MDT #
Posted by Dan Allen on June 12, 2003 at 06:00 PM MDT #
Posted by Pratik Patel on June 12, 2003 at 10:26 PM MDT #
Posted by Matt Raible on June 13, 2003 at 12:01 PM MDT #
Posted by billy vandory on June 18, 2010 at 09:13 PM MDT #
Posted by billy vandory on June 18, 2010 at 09:18 PM MDT #