Автор оригинала: Vlad Mihalcea.
Вступление
В этой статье мы рассмотрим, как мы можем переопределить режим сброса по умолчанию, используемый Hibernate.
Если вы загружаете режим гибернации изначально, а не как поставщик JPA, по умолчанию используется режим гибернации FlushMode. Будет использоваться стратегия AUTO
, которая, как описано в этой статье , не запускает очистку контекста сохранения перед выполнением собственного SQL-запроса.
Как переопределить режим сброса сеанса гибернации по умолчанию @vlad_mihalcea https://t.co/7II0qm0eDv https://t.co/7II0qm0eDv
Режим гибернации по умолчанию АВТОМАТИЧЕСКИ
Предполагая, что у нас нет Записи
сущности в нашей базе данных:
assertEquals( 0, ((Number) entityManager .createQuery( "select count(p) " + "from Post p") .getSingleResult() ).intValue() );
Если мы сохраняем Сообщение
сущность:
entityManager .persist( new Post() .setTitle( "High-Performance Java Persistence" ) );
и мы загружаем Hibernate изначально, используя SessionFactoryBuilder
, затем по умолчанию Режим сброса. АВТО
не вызовет сброс контекста сохранения при выполнении собственного SQL-запроса:
assertEquals( 0, ((Number) entityManager .createNativeQuery( "select count(*) " + "from post") .getSingleResult() ).intValue() );
Такое поведение происходит только в том случае, если Hibernate загружается с использованием класса SessionFactory
. Мы видим, что сброс задерживается до тех пор, пока транзакция Hibernate не будет готова к фиксации:
CALL NEXT VALUE FOR hibernate_sequence SELECT COUNT(*) FROM post -- o.h.e.t.i.TransactionImpl - committing INSERT INTO post ( title, id ) VALUES ( 'High-Performance Java Persistence', 1 )
При использовании JPA контекст сохранения сбрасывается при каждом выполнении запроса, будь то JPQL, API критериев или собственный SQL-запрос.
Как вручную переопределить режим сброса сеанса гибернации по умолчанию
Вы можете переопределить режим по умолчанию FlushMode
либо в Запрос
или Сессия
уровень.
Если вы заинтересованы только в изменении режима промывки
только на время текущего выполняемого запроса, то вы можете сделать это, как показано в следующем примере:
assertEquals( 1, ((Number) entityManager .createNativeQuery( "select count(*) " + "from post" ) .unwrap(org.hibernate.query.Query.class) .setHibernateFlushMode(FlushMode.ALWAYS) .getSingleResult() ).intValue() );
Режим Промывки. ВСЕГДА
режим указывает, что режим гибернации должен вести себя так же, как тип JPA FlushModeType. Таким образом, режим AUTO
запускает сброс контекста сохранения перед любым запросом , будь то JPQL, API критериев или собственный SQL-запрос.
Если вы хотите переопределить Режим сброса
для каждого запроса, выполняемого текущим режимом гибернации Сессия
, , затем вы можете изменить
Режим промывки
entityManager .unwrap(Session.class) .setHibernateFlushMode(FlushMode.ALWAYS);
Однако для этого потребуется вручную установить режим FlushMode. ВСЕГДА
для каждой Сессии
, что не очень удобно для разработчика приложения.
Как автоматически переопределить режим сброса сеанса гибернации по умолчанию
Вы можете определить конкретный Режим сброса
на уровне конфигурации гибернации с использованием org.hibernate.FlushMode
свойство конфигурации:
Таким образом, каждый Сеанс
будет использовать стратегию ВСЕГДА
промывки, поэтому нам не нужно вручную переопределять значение по умолчанию АВТОМАТИЧЕСКИЙ
режим промывки в Запрос
или Сессия
уровень.
Вывод
Установка режима FlushMode. ВСЕГДА
Стратегия желательна при начальной загрузке Hibernate изначально либо через Spring LocalSessionFactoryBean
, либо через Hibernate BootstrapServiceRegistryBuilder .
Таким образом, вы гарантируете согласованность чтения и записи, и собственные SQL-запросы будут включать все ожидающие изменения, которые планировалось выполнить во время сброса.