Использование OpenSessionInViewInterceptor, чтобы избежать LazyInitializationException - PullRequest
2 голосов
/ 26 августа 2010

Сначала я должен признать тот факт, что я новичок в EJB, JPA и Spring, поэтому многие из вещей, которые я считаю верными, могут быть ошибочными.

Я создаю приложение EJB, где естьсессионный компонент без сохранения состояния, используемый для получения многих объектов JPA (Hibernate).Проблема, которая, как я считаю, является широко распространенной, заключается в том, что я не могу проследить отношения этих сущностей, когда лица без гражданства возвращают какой-либо экземпляр.Я получаю страшное исключение LazyInitializationException.Во многих случаях я обнаружил, что используя активную выборку, я мог избежать исключения, но это больше походило на обходной путь, чем на реальное исправление.После долгих поисков, я обнаружил, что (так как я использую Spring), вероятно, самый навязчивый способ сделать это - использовать OpenSessionInViewInterceptor.

Чтение это выглядит так, как будто его легко использовать, ноЯ не могу отобразить файлы, упомянутые в статье.Одним из возможных объяснений является то, что я использую Spring 3, поэтому имена файлов могли измениться.У меня есть spring3app-servlet.xml , где объявляются бины.У меня также есть web.xml , где установлены фильтры (я полагаю, что этот файл использовался с пружиной 2.0, но он все еще работает с 3.0).

Дальнейший поиск позволил мне понять, чтоимена файлов были не единственной моей заботой, так как у меня нет никакого компонента SessionFactory, который, я считаю, необходим для того, чтобы это работало.Это привело меня к поиску информации о бине SessionFactory.

Этот поиск позволил мне понять, что мне, вероятно, нужны файлы .hbm.xml.Я не уверен, действительно ли нужны эти файлы или они необходимы для устаревших версий hibernate-spring.

tl; dr: Я хочу OpenSessionInViewInterceptor.Мне нужен бин SessionFactory?Нужны ли мне файлы .hbm.xml?Где я могу найти всю информацию, чтобы настроить это?

Редактировать:

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

1 Ответ

4 голосов
/ 26 августа 2010

Во-первых, если вы собираетесь использовать универсальное решение JPA, вы должны использовать OpenEntityManagerInViewFilter.Что делает что-то похожее на OpenSessionInViewInterceptor, но для JPA

Что касается сессионного компонента, вы всегда получите LazyInitializationException, так как объект загружается в другом сеансе.Ленивые поля доступны только в текущем http запросе.Если вы получите доступ к полю в другом запросе http, вы получите исключение LazyInitializationException.

(кстати, hibernate определяет запрос http как «Сеанс». Но сеанс Spring охватывает несколько запросов http. Да, это сбивает с толку).

Что вы можете сделать, чтобы избежать исключения LazyInitializationException:

  1. Перезагрузите сессионный компонент.Например:

    MyObject objectFromDb = objectDAO.find (objectFromSession.getId ());

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

    Hibernate.initialize (field);

(не забудьте использовать все дочерние поля)


Хорошо, так как этов том же сеансе вам нужен OpenEntityManagerInViewFilter / OpenSessionInViewInterceptor, который будет создавать сеанс Hibernate для каждого запроса Http.Поэтому поместите запись в ваш файл web.xml:

    <filter>
        <filter-name>JpaFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>JpaFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

OpenEntityManagerInViewFilter аналогичен.Также убедитесь, что ваш bean-компонент "entityManagerFactory" внедрен в ваш фильтр.

...