StaleObjectStateException после обновления объекта

Когда я пытаюсь зафиксировать свою сессию, а другой пользователь также изменил тот же объект, Hibernate выдает ошибку StaleObjectStateException.

Когда я пытаюсь восстановить это исключение, я вызываю:

session.refresh(<staleObject>)

Затем я еще раз вызываю фиксацию, которая ранее не удалась. Но staleObjectStateException снова появляется на том же объекте. Даже если нет никаких изменений, сделанных другим пользователем, я также проверил, что номер версии объекта совпадает с номером в нашей БД.

Кто-нибудь знает, что может быть не так? Есть ли у кого-нибудь лучшее представление о том, как изящно обрабатывать исключение, не закрывая и не открывая новый сеанс?

примечание: мы используем реализацию Single Session per View для нашего настольного (RCP) приложения.


person bvanvelsen    schedule 20.01.2012    source источник
comment
Это длительный сеанс гибернации?   -  person Santosh    schedule 20.01.2012
comment
@Santosh да, это долгоиграющая версия: если быть точным, она запускается при запуске нашего приложения и будет работать до тех пор, пока приложение не будет закрыто. Я знаю, что это не идеально, но это работает для нас...   -  person bvanvelsen    schedule 23.01.2012


Ответы (1)


Как вы упомянули, это длительный сеанс, согласно hibernate doc для метода refresh(),

Повторно прочитать состояние данного экземпляра из базовой базы данных. Не рекомендуется использовать это для реализации длительных сеансов, которые охватывают множество бизнес-задач. Однако этот метод полезен в некоторых особых обстоятельствах. Например, когда триггер базы данных изменяет состояние объекта при вставке или обновлении после выполнения прямого SQL (например, массового обновления) в том же сеансе после вставки BLOB-объекта или Clob-объекта.

Я бы предложил вам изменить стратегию использования одного сеанса в жизненном цикле приложения и использовать сеанс, но транзакцию, означающую открытие сеанса только тогда, когда вам нужно взаимодействовать с базой данных, и после этого закрыть сеанс.

Я не знаю о каких-либо принуждениях, которые у вас есть для использования длительного сеанса, это просто предложение.

person Santosh    schedule 23.01.2012
comment
Благодарим за ваше предложение. Я также прочитал Javadoc и увидел это утверждение. Но есть ли альтернатива? мы используем долгоживущие сеансы, потому что хотим повторно использовать bean-компоненты, запрашиваемые hibernate. Мы не хотим повторно запрашивать их каждый раз, когда пользователь выполняет какое-либо действие в пользовательском интерфейсе, просто чтобы количество запросов было низким (и производительность высокой) с того момента, как они у нас есть в памяти... - person bvanvelsen; 25.01.2012
comment
Вы можете использовать Кэш второго уровня (кэш L2). Если вы настроите это, Hibernate будет кэшировать запрошенные объекты. Перейдите по этой ссылке. - person Santosh; 25.01.2012