Рубрики
Без рубрики

Как переопределить режим сброса сеанса гибернации по умолчанию

Автор оригинала: 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-запросы будут включать все ожидающие изменения, которые планировалось выполнить во время сброса.