Правильное использование флеша () в JPA / Hibernate
Я собирал информацию о методе flush (), но я не совсем понимаю, когда использовать его и как правильно его использовать. Из того, что я читал, я понимаю, что содержимое контекста персистентности будет синхронизировано с базой данных, то есть выдача выдающихся заявлений или обновление данных сущности.
Теперь я получил следующий сценарий с двумя сущностями A
и B
(в отношениях один к одному, но не применяемыми или смоделированными JPA). A
имеет составную PK, которая установлена вручную, а также имеет автоматически генерируемую recordId
IDENTITY. Этот recordId
должен быть записан в объект B
как внешний ключ для A
Я сохраняю A
и B
в одной транзакции. Проблема заключается в том, что автоматически созданное значение A.recordId
недоступно в транзакции, если я не сделаю явный вызов em.flush()
после вызова em.persist()
на A
(Если у меня есть автоматически сгенерированный идентификатор PK, тогда значение напрямую обновляется в сущности, но здесь это не так).
Может ли em.flush()
причинить вред при использовании в транзакции?
- Поведение MySQL «выберите для обновления»
- База данных.BeginTransaction vs Transactions.TransactionScope
- как преобразовать data.frame в транзакции для arules
- Как использовать TransactionScope в C #?
- Использует ли атрибут Spring @Transactional собственный метод?
Вероятно, точные данные em.flush()
зависят от реализации. В общем, в любом случае, провайдеры JPA, такие как Hibernate, могут кэшировать инструкции SQL, которые они должны отправлять в базу данных, часто до тех пор, пока вы действительно не совершите транзакцию. Например, вы вызываете em.persist()
, Hibernate помнит, что он должен сделать базу данных INSERT, но фактически не выполняет инструкцию, пока вы не совершите транзакцию. Afaik, это в основном сделано по соображениям производительности.
В некоторых случаях в любом случае вы хотите, чтобы инструкции SQL выполнялись немедленно; обычно, когда вам нужен результат некоторых побочных эффектов, таких как автогенерированный ключ или триггер базы данных.
Что em.flush()
, это очистить внутренний кеш инструкций SQL и немедленно выполнить его в базе данных.
Итог: никакого вреда не сделано, только у вас может быть (незначительная) производительность, так как вы переопределяете решения поставщика JPA в отношении наилучшего времени для отправки инструкций SQL в базу данных.
Фактически, em.flush()
, делает больше, чем просто отправляет кэшированные команды SQL. Он пытается синхронизировать контекст персистентности с базой данных. Это может вызвать много времени на процессы, если ваш кеш содержит синхронизированные коллекции.
Предостережение при использовании.