views:

220

answers:

1

When hibernate closes a session, the purpose of close is basically to close the underlying connection and the clean up the first level cache. Why the flush also does not happens automatically here?

+2  A: 

From a transactional point of view, flushing is very different from closing the session and flush should occur inside the boundaries of a transaction (or at commit time):

Ending a Session usually involves four distinct phases:

  • flush the session
  • commit the transaction
  • close the session
  • handle exceptions

On the other hand, closing a Session (and the underlying connection) should be done after a transaction has ended (the behavior of a pending transaction when closing a connection is undefined).

There is thus no reason to do anything on close and to promote bad semantics and it makes perfect sense to have distinct operations.

To sum up:

  1. just use a transaction and proper demarcation as you're supposed to (and the session will get flushed at commit time if required, depending on the FlushMode).
  2. use SessionFactory#getCurrentSession() and you won't have to Session#close() yourself (the Session will get closed for you at commit time).
Pascal Thivent
@Pascal, I think you did not really answer the op's question. He did not suggest that flushing and closing the session are the same but rather that if the session is dirty then upon closing it flush should also be called. This does make sense to me if one is using FlushMode.Auto and they update a persistent object then I would think Hibernate should take care of flushing the object at the time it thinks it has do, Hibernate should not ignore the change. Which is I think might happen if flush isn't called.
Ittai
@Ittai I've clarified my answer (which wasn't clear enough) and I tried to explain why I don't agree with you.
Pascal Thivent
@Pascal, thank you for your clarifications but I still don't agree. Regarding Item2, that's irrelevant in my case as I use the session-per-request pattern and sometimes I need the session to remain open after a commit. Regarding Item1, that's exactly what I don't feel comfortable with- Why use a transaction for a single update? I see a transaction as a way to ensure consistency over a few different commands (group them to a unit of work). But when there's only one command, why should we use a transaction? (BTW, I used to use JDBC all the time and this might affect my concenptions).
Ittai
@Pascal, On the same subject do you disagree with the answer I was given here (http://stackoverflow.com/questions/3931162/will-hibernate-flush-my-updated-persistent-object-when-calling-session-closeus/3931226#3931226)?
Ittai
@Ittai No SQL statement can be send to a database outside of a database transaction.
Pascal Thivent
@Ittai I'll answer the other question.
Pascal Thivent
@Pascal regarding "No SQL...", You mean No Insert/Update/Delete... right? Because regarding selects that does not make sense. Also I'd appreciate greatly a reference to this statement
Ittai
@Ittai No, I mean any SQL statement, including a SELECT. I suggest reading [Non-transactional data access and the auto-commit mode](http://community.jboss.org/wiki/Non-transactionaldataaccessandtheauto-commitmode).
Pascal Thivent
@Pascal thanks, I'll read it now.
Ittai