Я получаю это исключение в контроллере веб-приложения на основе Spring Framework, использующего Hibernate.Я пробовал много способов противостоять этому, но не смог разрешить его.
В методе контроллера, handleRequestInternal
, в базу данных поступают вызовы, в основном для «чтения», если только это не действие отправки.Я использовал Spring Session, но перешел на getHibernateTemplate()
, и проблема все еще остается.
По сути, этот второй вызов базы данных вызывает это исключение.То есть:
1) getEquipmentsByNumber(number)
{сначала оборудование выбирается из БД на основе «числа», у которого есть список свойств, а у каждого свойства есть список значений.Я перебираю эти значения (строки примитивных объектов) для чтения переменных)
2) getMaterialById(id)
{выбирает материалы на основе идентификатора}
Я понимаю, что второй вызов, скорее всего,, делает сеанс "сбрасывать", но я только "читаю" объекты, тогда почему второй вызов вызывает исключение состояния устаревшего объекта в свойстве Equipment, если ничего не изменилось?
Я не могу очистить кеш после вызова, так как это вызывает исключения LazyException для объектов, которые я передаю в представление.
Я прочитал это: https://forums.hibernate.org/viewtopic.php?f=1&t=996355&start=0, но не смог решить проблемуна основе предоставленных предложений.
Как я могу решить эту проблему?Любые идеи и мысли приветствуются.
ОБНОВЛЕНИЕ: Я только что проверил, что в функции getEquipmentsByNumber()
после чтения переменных из списка свойств я делаю это: getHibernateTemplate().flush();
итеперь исключение находится в этой строке, а не в вызове для выборки материала (то есть getMaterialById(id)
).
ОБНОВЛЕНИЕ: Перед явным вызовом сброса я удаляю объект из кэша сеанса, поэтомучто в кэше не осталось устаревших объектов.
getHibernateTemplate().evict(equipment);
getHibernateTemplate().flush();
ОК, так что теперь проблема перешла к следующей выборке из БД после того, как я это сделал.Я полагаю, что я должен пометить методы как синхронизированные и исключить объекты, как только я закончу читать их содержимое!звучит не очень хорошо.
ОБНОВЛЕНИЕ: Сделан метод handleRequestInternal
"синхронизирован".Ошибка исчезла.Конечно, не лучшее решение, но что делать!Попытался в handleRequestInternal
закрыть текущий сеанс и открыть новый.Но это может привести к тому, что другие части приложения не будут работать должным образом.Пытался использовать ThreadLocal
, который тоже не работал.