Will Hibernate flush my updated persistent object when calling session.close() (using FlushMode.AUTO)?
No it won't, and you should use a transaction with well defined boundaries. Quoting Non-transactional data access and the auto-commit mode:
Working nontransactionally with Hibernate
Look at the following code, which
accesses the database without
transaction boundaries:
Session session = sessionFactory.openSession();
session.get(Item.class, 123l);
session.close();
By default, in a Java SE environment
with a JDBC configuration, this is
what happens if you execute this
snippet:
- A new Session is opened. It doesn’t obtain a database connection at this
point.
- The call to get() triggers an SQL SELECT. The Session now obtains a JDBC
Connection from the connection pool.
Hibernate, by default, immediately
turns off the autocommit mode on this
connection with setAutoCommit(false).
This effectively starts a JDBC
transaction!
- The SELECT is executed inside this JDBC transaction. The Session is
closed, and the connection is returned
to the pool and released by Hibernate
— Hibernate calls close() on the JDBC
Connection. What happens to the
uncommitted transaction?
The answer to that question is, “It
depends!” The JDBC specification
doesn’t say anything about pending
transactions when close() is called on
a connection. What happens depends on
how the vendors implement the
specification. With Oracle JDBC
drivers, for example, the call to
close() commits the transaction! Most
other JDBC vendors take the sane route
and roll back any pending transaction
when the JDBC Connection object is
closed and the resource is returned to
the pool.
Obviously, this won’t be a problem for
the SELECT you’ve executed, but look
at this variation:
Session session = getSessionFactory().openSession();
Long generatedId = session.save(item);
session.close();
This code results in an INSERT
statement, executed inside a
transaction that is never committed or
rolled back. On Oracle, this piece of
code inserts data permanently; in
other databases, it may not. (This
situation is slightly more
complicated: The INSERT is executed
only if the identifier generator
requires it. For example, an
identifier value can be obtained from
a sequence without an INSERT. The
persistent entity is then queued until
flush-time insertion — which never
happens in this code. An identity
strategy requires an immediate INSERT
for the value to be generated.)
Bottom line: use explicit transaction demarcation.