Jeff Sternal
Jeff Sternal

Reputation: 48583

Why does Hibernate only Auto-Flush inside a transaction?

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."

Upvotes: 5

Views: 4887

Answers (1)

JB Nizet
JB Nizet

Reputation: 691755

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.

Upvotes: 3

Related Questions