Будет ли Hibernate очищать мой обновленный постоянный объект при вызове session.close () с FlushMode.AUTO? - PullRequest
5 голосов
/ 14 октября 2010

Если установлено значение FlushMode.AUTO, будет ли Hibernate очищать мой обновленный постоянный объект при вызове session.close ()?

Я знаю, что session.close () обычно не сбрасывает сеанс, но я не уверен, как FlushMode.AUTO влияет на это.

Из документов:

FlushMode.AUTO
Сеанс иногда сбрасывается перед выполнением запроса, чтобы запросы никогда не возвращали устаревшее состояние. Это режим сброса по умолчанию.

Значит ли это, что я могу положиться на Hibernate, чтобы убедиться, что мои изменения иногда сбрасываются до закрытия сеанса?

Пример небольшого кода:

Session session = HibernateSessionFactory.getSession();  
PersistedObject p = session.get(PersistedObject.class,id);  
p.setSomeProperty(newValue);  
session.close();

UPDATE
Согласно документам это места, где сеанс будет сбрасываться (при использовании AUTO)

  • до выполнения некоторых запросов
  • от org.hibernate.Transaction.commit ()
  • из Session.flush ()

Это ничего не говорит о Session.close ()

Ответы [ 2 ]

13 голосов
/ 14 октября 2010

Будет ли Hibernate очищать мой обновленный постоянный объект при вызове session.close () (используя FlushMode.AUTO)?

Нет, не будет, и вам следует использоватьсделка с четко определенными границами .Цитирование Нетранзакционный доступ к данным и режим автоматической фиксации :

Работа без транзакций с Hibernate

Посмотрите на следующий код, который обращается к базе данных без транзакцииграницы:

Session session = sessionFactory.openSession(); 
session.get(Item.class, 123l); 
session.close(); 

По умолчанию в среде Java SE с конфигурацией JDBC это происходит при выполнении этого фрагмента:

  1. Открывается новый сеанс.На этом этапе он не получает соединение с базой данных.
  2. Вызов get () запускает SQL SELECT.Теперь сеанс получает соединение JDBC из пула соединений.Hibernate по умолчанию немедленно отключает режим автоматической фиксации для этого соединения с помощью setAutoCommit (false).Это эффективно запускает транзакцию JDBC!
  3. SELECT выполняется внутри этой транзакции JDBC.Сеанс закрывается, и соединение возвращается в пул и освобождается Hibernate - Hibernate вызывает close () для JDBC-соединения.Что происходит с незафиксированной транзакцией?

Ответ на этот вопрос: «Это зависит!» Спецификация JDBC ничего не говорит о незавершенных транзакциях, когда close () вызывается для соединения.Что происходит, зависит от того, как поставщики реализуют спецификацию.Например, для драйверов JDBC Oracle вызов close () фиксирует транзакцию!Большинство других поставщиков JDBC выбирают вменяемый маршрут и откатывают все ожидающие транзакции, когда объект JDBC-соединения закрыт и ресурс возвращен в пул.

Очевидно, это не будет проблемой для SELECT you 'мы выполнили, но посмотрите на эту вариацию:

Session session = getSessionFactory().openSession(); 
Long generatedId = session.save(item); 
session.close(); 

Этот код приводит к выражению INSERT, выполняемому внутри транзакции, которая никогда не фиксируется и не откатывается.В Oracle этот фрагмент кода вставляет данные постоянно;в других базах данных может и нет.(Эта ситуация немного сложнее: INSERT выполняется только в том случае, если этого требует генератор идентификаторов. Например, значение идентификатора может быть получено из последовательности без INSERT. Затем постоянная сущность ставится в очередь до вставки времени сброса- что никогда не происходит в этом коде . Стратегия идентификации требует немедленной вставки для генерируемого значения.)

Итог: используйте явное разграничение транзакции.

0 голосов
/ 14 октября 2010

закрытие сессии будет всегда сбрасывать всю работу в базу данных.Flushmode.AUTO сбрасывает работу в базу данных, когда есть изменения, и вы запрашиваете таблицу с измененными записями.

...