2013-05-25 4 views
27

я получил ошибку, которая выглядит следующим образом:Не удалось инициализировать прокси - не сессии

Не удалось инициализировать прокси - не сессии

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

  1. Я отправил запрос в приложение с помощью метода POST. Это создает PDF на лету и показывает пользователю.

  2. Сразу после этого запроса отправлю другое, но через ajax запрос. Это создаст тот же PDF-файл, но сохранит его в БД.

Ошибка показывает, что запрос не может быть выполнен из-за ошибки «не инициализировать прокси - без сеанса».

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

Надеюсь, кто-то может помочь мне понять, что происходит.

+0

Ошибка в сторону, почему вы создали два разных вызова для создания PDF-файла? Сделайте это один раз, продолжайте его, а затем извлеките из базы данных. – Makoto

+0

Когда я писал вопрос, я думал то же самое, что вы предлагаете. Но я хотел, чтобы кто-то с немного большим опытом подтвердил то же самое. И просто для того, чтобы сделать его более полезным ... Можете ли вы объяснить, почему ошибка «не может инициализировать прокси - без сеанса» происходит в этом конкретном сценарии ?. заранее спасибо. –

+0

Hibernate выпуск. Покажите нам код, стоящий за вызовом Ajax, чтобы мы могли помочь вам. – Jukka

ответ

67

Ваша проблема заключается в том, что сеанс спящего режима работает только для одного запроса. Он открывается в начале запроса и закрывается в конце. Вы догадались, что ответ: сеанс Hibernate закрыт до того, как оба запроса будут завершены.

Что именно происходит? Объекты вашего объекта живут во время обоих запросов. Как? Они хранятся в сеансе HTTP (это другая вещь, называемая сеансом). Вы не предоставляете много информации о используемой структуре, поэтому я не могу дать вам более подробную информацию, но, несомненно, используемая вами инфраструктура каким-то образом сохраняет ваши сущности в сеансе HTTP. Таким образом, структура упрощает работу с одними и теми же объектами для нескольких запросов.

Когда начинается обработка второго запроса, код пытается получить доступ к некоторому объекту (обычно к элементу коллекции), который инициализируется с помощью спящего режима. Сущность не привязана к сеансу гибернации, и поэтому спящий режим не может инициализировать прокси-сервер hibernate перед его чтением. Вы должны открыть сеанс и снова присоединить свой объект к нему в начале обработки запроса ajax.

EDIT:

Я попытаюсь дать краткое объяснение того, что происходит за сценой. Все веб-фреймворки java имеют один или несколько сервлетов, которые обрабатывают запросы. Сервлет обрабатывает каждый запрос (HttpRequest), создавая новый поток, который, наконец, произведет ответ (HttpResponse). Метод, обрабатывающий каждый запрос, выполняется внутри этого потока.

В начале обработки запроса ваше приложение должно выделить ресурсы, необходимые для обработки (сеанс транзакции, спящий режим и т. Д.). По завершении цикла обработки эти ресурсы освобождаются (транзакция завершена, сеанс hibernate закрыт, JDBC-соединения освобождены и т. Д.). Жизненный цикл этих ресурсов может управляться вашей инфраструктурой или может быть выполнен с помощью вашего кода.

Чтобы поддерживать состояние приложения в протоколе без учета состояния как HTTP, у нас есть объект HttpSession. Мы (или рамки) помещаем HttpSession информацию, которая остается актуальной между разными циклами запросов одного и того же клиента.

Во время обработки первого запроса hibernate считывает (лениво) объект из базы данных. Из-за ленивой инициализации некоторые части структуры этого объекта являются спящими прокси-объектами. Эти объекты связаны с сеансом hibernate, который их создал.

Рамка находит объект из предыдущего запроса в объекте HttpSession, когда вы пытаетесь обработать второй запрос. Затем он пытается получить доступ к свойству из дочернего объекта, который был лениво инициализирован и теперь является прокси-объектом спящего режима. Прокси-объект hibernate является имитацией реального объекта, который будет запрашивать сессию hibernate для заполнения его информацией из базы данных, когда кто-то пытается получить доступ к одному из своих свойств. Это то, что пытается сделать ваш прокси-сервер hibernate. Но его сеанс был закрыт в конце предыдущей обработки запроса, поэтому теперь у него нет сеанса спящего режима для использования, чтобы быть гидратированным (заполненным реальной информацией).

Обратите внимание: возможно, что вы уже открыли сеанс спящего режима в начале второго запроса, но он не знает об объекте, который содержит прокси-объект, потому что этот объект был прочитан другим спящим сеансом. Вы должны повторно присоединить объект к новому сеансу спящего режима.

Существует много дискуссий о том, как повторно присоединить отдельный объект, но самый простой подход - session.update(entity).

Надеюсь, это поможет.

+0

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

+0

Вы поняли. Те же данные, которые вы упоминаете, - это сущность, которая существует в вашей пользовательской сессии (HttpSession). Во время второго запроса hibernate пытается заполнить прокси-объект (который является имитацией реального объекта) информацией из базы данных. Прежде чем пытаться выполнить запросы, которые будут извлекать данные, hibernate пытается найти объект сеанса hibernate, связанный с этим прокси-объектом. Но прокси-объект не связан с сеансом спящего режима. Объект-отец объекта-прокси был отделен от сеанса, когда был завершен первый запрос. – nakosspy

+0

отредактирован с более подробной информацией о циклах обработки запросов – nakosspy