2010-11-25 4 views
103

Я собирал информацию о методе flush(), но я не совсем понимаю, когда его использовать и как правильно его использовать. Из того, что я читал, я понимаю, что содержимое контекста персистентности будет синхронизировано с базой данных, т.е. е. выдача невыполненных заявлений или обновление данных объекта.Правильное использование flush() в JPA/Hibernate

Теперь у меня есть следующий сценарий с двумя объектами A и B (в отношениях «один к одному», но не применяемый или смоделированный JPA). A имеет составной ПК, который установлен вручную, а также имеет автоматически генерируемое поле IDENTITY recordId. Этот recordId должен быть записан объекту B в качестве внешнего ключа к A. Я сохраняю A и B за одну транзакцию. Проблема заключается в том, что автоматически генерируемое значение A.recordId недоступно в транзакции, если я не сделаю явный вызов em.flush() после звонка em.persist() по телефону A. (Если у меня есть автогенерированный идентификатор PK, тогда значение напрямую обновляется в объекте, но здесь это не так.)

Может ли em.flush() причинить какой-либо вред при его использовании в рамках транзакции?

ответ

128

Возможно, конкретные данные em.flush() зависят от реализации. Как правило, провайдеры JPA, такие как Hibernate, могут кэшировать инструкции SQL, которые они должны отправлять в базу данных, часто до тех пор, пока вы фактически не совершите транзакцию. Например, вы вызываете em.persist(), Hibernate помнит, что он должен сделать базу данных INSERT, но на самом деле не выполняет инструкцию до фиксации транзакции. Afaik, это в основном сделано по соображениям производительности.

В некоторых случаях в любом случае вы хотите, чтобы инструкции SQL выполнялись немедленно; обычно, когда вам нужен результат некоторых побочных эффектов, таких как автогенерированный ключ или триггер базы данных.

Что нужно сделать em.flush(), это очистить внутренний тайник команд SQL и немедленно выполнить его в базе данных.

Нижняя строка: никакого вреда не сделано, только вы можете получить (незначительное) действие, так как вы переопределяете решения поставщика JPA в отношении наилучшего времени для отправки инструкций SQL в базу данных.

+1

Что он сказал. em.flush() поведение эха java.io.Flushable.flush(), где все буферизованные данные отправляются в любой пункт назначения. – Erik 2010-11-25 10:29:42

0

Фактически, em.flush(), больше, чем просто отправляет кешированные команды SQL. Он пытается синхронизировать контекст персистентности с базой данных. Это может вызвать много времени на процессы, если ваш кеш содержит синхронизированные коллекции.

Предостережение при использовании.

Смежные вопросы