Почему Hibernate только Auto-Flush внутри транзакции? - PullRequest
5 голосов
/ 07 марта 2011

В чем причина такого поведения?

Если по какой-то причине я выполняю две подходящие операции вне транзакции (не рекомендуется, я знаю!), И я настроил Hibernate на автоматическую очистку, я бы ожидал автоматическую очистку, если вторая операция - это та, которая должна вызывать автоматическую очистку (например, list, iterate или executeUpdate).

Это именно то, что произошло бы, если бы не явная проверка во второй строке autoFlushIfRequried метода:

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();
}

Обновление : Спасибо axtavt за обнаружение проблемы Hibernate, которая вызвала это изменение (в 3.2): FlushMode.AUTO -> COMMIT при выходе за пределы транзакции .

Связанная проблема по-прежнему открыта: задержка вставки IDENTITY в случае FlushMode.MANUAL / NEVER , но ни одно из обсуждений не дает обоснования для высказывания «При работе вне транзакции FlushMode.AUTO является плохим вещь. "

1 Ответ

2 голосов
/ 07 марта 2011

Поскольку документация для FlushMode гласит:

Сеанс иногда сбрасывается перед выполнением запроса, чтобы гарантировать, что запросы никогда не вернут устаревшее состояние.Это режим сброса по умолчанию.

Таким образом, авто не означает то, что вы думаете, это означает.Возможно, имя выбрано неверно, но это не означает, что после каждой операции сеанса выполняется сброс.Таким образом, он не похож на автокоммит JDBC, который делает коммит после когда-либо оператора JDBC.

...