This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I'm having a bit of a problem implementing an OSIV setup and I've traced it down to some heartburn I'm having with Hibernate sessions and transactions.
Given the following sample code:
I'm rather surprised to find that the log statement of line  emits false. I have the following in my Hibernate config file:
so shouldn't the session be maintained in thread-local storage?
Lines  and  show that tx and sf.getCurrentSession().getTransaction() reflect different Transaction instances, one active one not -- which is not surprising if there are two different Session instances.
What vital concept am I missing? I had assumed that once a session and transaction were established as in lines 1 through 3, that I'd be able to fetch the session and transaction later on down the road to use for queries and the like.
Obviously, without getting this working, an OSIV setup is not possible.
P.S. I'm not using EJBs or a JEE container, so no JTA. [ May 01, 2008: Message edited by: Bear Bibeault ]
Does it influence your thinking to know that line 4 in the following code returns true? A consistent use of getCurrenctSession() seems to generate two logically equal instances, whereas using openSession() does not.
Not sure if this answers any questions you have, or if it just contributes to the talking point?
Obtains the current session. The definition of what exactly "current" means controlled by the CurrentSessionContext impl configured for use.
Note that for backwards compatibility, if a CurrentSessionContext is not configured but a JTA TransactionManagerLookup is configured this will default to the JTASessionContext impl.
Session openSession(Connection connection)
Open a Session on the given connection.
Note that the second-level cache will be disabled if you supply a JDBC connection. Hibernate will not be able to track any statements you might have executed in the same transaction. Consider implementing your own ConnectionProvider.
I guess I'm still confused as to what's happening in my code snippet. If a session is opened with openSession() I'd assume that a new session is created. I'd then expect a call to getCurrentSession() to return that session rather than create a new one. If a new one is created by getCurrentSession() but subsequent calls to getCurrentSession() return that same session, under what conditions does getCurrentSession() create a new session and when does it return the existing session?
Originally posted by Bear Bibeault: I guess I'm still confused as to what's happening in my code snippet. If a session is opened with openSession() I'd assume that a new session is created. I'd then expect a call to getCurrentSession() to return that session rather than create a new one. If a new one is created by getCurrentSession() but subsequent calls to getCurrentSession() return that same session, under what conditions does getCurrentSession() create a new session and when does it return the existing session?
What I think is being said is that openSession() and getCurrentSession() don't talk to each other, or should I say, openSession() just returns you a Session and doesn't do anything internally to store it in some variable, so that it can know to either create a new Session or return the one already created.
Also meaning that is you are going to use getCurrentSession() Hibernate expects that that is all you are going to be calling, that you would never be calling openSession() at all, even at first.
Or easier put, lets look at the Hibernate code for openSession() at least the version of the method that all the other versions call.
It basically creates new and returns it on the same line.
Now if we look at the getCurrentSession() method it is actually looking to use a currentSessionContext, which stores the Session, or creates new, if the context hadn't created a Session yet.
This is definitely just a design decision, that does a great job of seperation of concerns here. Basically saying why add the whole extra context in openSession() if it isn't necessary, since most people will be using openSession in their context of not using getCurrentSession. Also to keep openSession() backwards compatible with older code written to older Hibernate code.
And I am also just conjecturing here, not having been in the room when the Hibernate guys made their design decisions.
So we use either current or open, but not both. That wasn't made clear in the API or in the Bauer book. (Or if it was, I missed it).
I found this useful when i was trying to understand about transactions and sessions in Hibernate. That has a section "Transaction demarcation with plain JDBC" (when JTA is not used) which explains the difference of using openSession() and getCurrentSession().