问题
What is the rationale behind this behavior?
If for some reason I execute two suitable operations outside a transaction (not recommended, I know!) and I've configured Hibernate to auto-flush, I would expect it to auto-flush if the second operation is one that should trigger an auto-flush (like list
, iterate
, or executeUpdate
).
That's exactly what would happen, if not for the explicit check on the second line of the autoFlushIfRequried
method:
protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
errorIfClosed();
if ( ! isTransactionInProgress() ) {
// do not auto-flush while outside a transaction
return false;
}
AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
autoFlushEventListener[i].onAutoFlush(event);
}
return event.isFlushRequired();
}
Update: Thank you axtavt for finding the Hibernate issue that prompted this change (in 3.2): FlushMode.AUTO -> COMMIT when outside a transaction.
A related issue is still open: delay IDENTITY insertions in the case of FlushMode.MANUAL/NEVER, but neither discussion provides the rationale for saying "When operating outside a transaction, FlushMode.AUTO is a bad thing."
回答1:
Because the docummentation for FlushMode
says
The Session is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode.
So, auto doesn't mean what you think it means. The name is, arguably, badly chosen, but it doesn't mean a flush is made after each session operation. It's thus not similar to JDBC's autocommit, which makes a commit after ever JDBC statement.
来源:https://stackoverflow.com/questions/5221745/why-does-hibernate-only-auto-flush-inside-a-transaction