Ответы:
Сброс сеанса заставляет Hibernate синхронизировать состояние в памяти Session
с базой данных (т.е. записывать изменения в базу данных). По умолчанию Hibernate автоматически сбрасывает изменения за вас:
Разрешение явной очистки Session
дает более тонкий контроль, который может потребоваться в некоторых обстоятельствах (для получения назначенного идентификатора, для управления размером сеанса, ...).
id = session.save(obj);
и транзакция фиксируется на следующей строке, но obj не сохраняется в БД, почему? 2) Я сохранил obj, используя session.save(obj);
с фиксацией, а при возврате я использовал return obj.getprimaryID();
В этом случае obj сохраняется в БД. Так почему происходит такое поведение?
Как правильно сказано в ответах выше, позвонив flush()
мы заставляем спящий режим выполнять команды SQL в базе данных. Но поймите, что изменения еще не «зафиксированы». Итак, после выполнения сброса и до совершения фиксации, если вы напрямую обращаетесь к БД (например, из приглашения SQL) и проверяете измененные строки, вы НЕ увидите изменений.
Это то же самое, что открыть 2 сеанса команд SQL. И изменения, сделанные за 1 сеанс, не видны другим, пока не будут зафиксированы.
Я знаю только то, что когда мы вызываем, session.flush()
наши операторы выполняются в базе данных, но не фиксируются.
Предположим, мы не вызываем flush()
метод для объекта сеанса, и если мы вызываем метод фиксации, он будет выполнять внутреннюю работу по выполнению операторов в базе данных, а затем фиксации.
commit=flush+commit
(в случае функциональности)
Таким образом, я прихожу к выводу, что когда мы вызываем метод flush () для объекта Session, он не получает фиксацию, а попадает в базу данных и выполняет запрос, а также получает откат.
Для фиксации мы используем commit () для объекта транзакции.
При очистке сеанса данные, которые в данный момент находятся в сеансе, синхронизируются с данными в базе данных.
Подробнее на сайте Hibernate:
flush()
полезно, потому что нет абсолютно никаких гарантий относительно того, когда сеанс выполняет вызовы JDBC, только порядок, в котором они выполняются, за исключением того, что вы используете flush()
.
Вы можете использовать, flush
чтобы принудительно реализовать ограничения проверки и обнаружить их в известном месте, а не при фиксации транзакции. Это может быть commit
вызвано неявно некоторой логикой фреймворка, декларативной логикой, контейнером или шаблоном. В этом случае любое созданное исключение может быть трудно поймать и обработать (оно может быть слишком большим в коде).
Например, если вы создаете save()
новый объект EmailAddress, который имеет уникальное ограничение на адрес, вы не получите сообщение об ошибке, пока не зафиксируете.
Вызов flush()
заставляет строку быть вставленной, вызывая исключение, если есть дубликат.
Однако после исключения вам придется откатить сеанс.
Я просто хотел бы объединить все ответы, данные выше, а также связать метод Flush () с Session.save (), чтобы придать большее значение
Hibernate save () можно использовать для сохранения объекта в базе данных. Мы можем вызывать этот метод вне транзакции, поэтому мне не нравится этот метод для сохранения данных. Если мы используем это без транзакции и у нас есть каскадирование между сущностями, то будет сохранена только основная сущность, если мы не очистим сеанс.
flush (): принудительно очищает сеанс. Он используется для синхронизации данных сеанса с базой данных.
Когда вы вызываете session.flush (), операторы выполняются в базе данных, но не фиксируются. Если вы не вызываете session.flush () и если вы вызываете session.commit (), внутренний метод commit () выполняет оператор и фиксируется.
Итак, commit () = flush + commit. Таким образом, session.flush () просто выполняет операторы в базе данных (но не фиксирует), а операторы больше НЕ В ПАМЯТИ. Это просто заставляет сеанс промывать.
Несколько важных моментов:
Следует избегать сохранения за пределами границ транзакции, иначе сопоставленные сущности не будут сохранены, что приведет к несогласованности данных. Забыть о промывке сеанса - это нормально, потому что это не вызывает никаких исключений или предупреждений. По умолчанию Hibernate автоматически сбрасывает изменения для вас: перед выполнением некоторых запросов при фиксации транзакции Разрешение явной очистки сеанса дает более точный контроль, который может потребоваться в некоторых обстоятельствах (для присвоения идентификатора, для управления размером сеанса )
flush()
Метод вызывает Hibernate промывать сессию. Вы можете настроить Hibernate для использования режима очистки для сеанса с помощью setFlushMode()
метода. Чтобы получить режим очистки для текущего сеанса, вы можете использовать getFlushMode()
метод. Чтобы проверить, грязная ли сессия, вы можете использовать isDirty()
метод. По умолчанию Hibernate управляет сбросом сеансов.
Как указано в документации:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
Промывка
Сброс - это процесс синхронизации состояния контекста постоянства с базовой базой данных.
EntityManager
И гибернацииSession
выставить набор методов, с помощью которых разработчик может изменять постоянное состояние субъекта.Контекст персистентности действует как транзакционный кэш с отложенной записью, помещая в очередь любое изменение состояния объекта. Как и любой кэш с отложенной записью, изменения сначала применяются в памяти и синхронизируются с базой данных во время очистки. Вровень операция принимает каждое изменение состояния лица и переводит его в
INSERT
,UPDATE
илиDELETE
заявление.Стратегия очистки задается flushMode текущего запущенного сеанса Hibernate. Хотя JPA определяет только две стратегии очистки (
AUTO
иCOMMIT
), Hibernate имеет гораздо более широкий спектр типов очистки:
ALWAYS
: Очищает сеанс перед каждым запросом;AUTO
: Это режим по умолчанию, и он очищает сеанс только при необходимости;COMMIT
: Сессия пытается отложить очистку до тех пор, пока текущая транзакция не будет зафиксирована, хотя она также может быть сброшена преждевременно;MANUAL
: Сброс сеанса делегируется приложению, которое должно вызыватьSession.flush()
явно, чтобы применить изменения контекста постоянства.По умолчанию Hibernate использует
AUTO
режим сброса, который запускает сброс в следующих случаях:
- до совершения Транзакции;
- перед выполнением запроса JPQL / HQL, который перекрывается с действиями объекта в очереди;
- перед выполнением любого собственного SQL-запроса, не имеющего зарегистрированной синхронизации.
У звонка EntityManager#flush
есть побочные эффекты . Его удобно использовать для типов сущностей со сгенерированными значениями идентификаторов (значениями последовательности): такой идентификатор доступен только при синхронизации с нижележащим уровнем сохраняемости. Если этот идентификатор требуется до завершения текущей транзакции (например, для целей ведения журнала), требуется очистка сеанса.