Spring JSF OpenSessionInViewFilter - PullRequest
       34

Spring JSF OpenSessionInViewFilter

3 голосов
/ 14 июня 2011

У меня большие проблемы с работой OpenSessionInViewFilter с использованием Spring 3.0.2, hibernate3 и jsf2.

сценарий:

есть BusinessCaseEntity с несколькими простыми информационными свойствами(типа string и int) и список сопоставленных EmployeeEntities.Этот список отображается с помощью

fetch = FetchType.LAZY

. Прежде всего, я загружаю список всех BusinessCases и показываю их в таблице.для этой цели я использую класс дао.бизнес-шкафы с их простыми свойствами отображаются.если я выбираю конкретный бизнес-случай, я хочу, например, показать подключенных сотрудников.поэтому я просто хочу использовать метод get для объекта businesscase -> getEmployees ()

, с моим простым пониманием Spring и Hibernate, я знаю, что BusinessCaseEntity в это время отделен от любого Spring и Hibernate (session) в бэкэнде, и появляется известное исключение LazyLoadingException.

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

настроил фильтр в моем web.xml, и я сделал небольшой подкласс OpenSessionInViewFilter изПришло время сделать некоторые выходные данные для отладки.

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

2011-06-14 19:19:49,734 DEBUG HibernateFilter:239 - Using SessionFactory 'sessionFactory' for OpenSessionInViewFilter
2011-06-14 19:19:49,734 DEBUG HibernateFilter:66 - Opening single Hibernate Session in OpenSessionInViewFilter
Jun 14, 2011 7:19:49 PM com.sun.facelets.FaceletViewHandler handleRenderException
SEVERE: Error Rendering View[/web/caseDetails.xhtml]
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.frivak.cat.db.entities.BusinessCaseEntity.caseClientList, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
LOTS OF STACKTRACE ...
2011-06-14 19:19:49,879 DEBUG HibernateFilter:92 - Closing single Hibernate Session in OpenSessionInViewFilter

Могу ли я как-то неправильно понять цель OpenSessionInViewFilter?

Я совершенно потерян и буду очень признателен за помощь.

спасибо - Крис

Ответы [ 2 ]

1 голос
/ 30 июня 2014

Я отказался от попыток использовать Spring OpenSessionInViewFilter.Я реализовал JSF Phase Listeners для выполнения этой работы, как указано ниже: http://assenkolov.blogspot.com.br/2008/04/open-session-in-view-with-jsf-and.html. Решение сработало для меня.

Полный пост ниже (если ссылка не работает):

Я ожидал, что быстрый сеанс Google сразу же предоставит стандартное решение для этой ситуации, но все пошло не так.

Проблема: я хочу открыть Session in View для JSF / Springприложение.Хорошо, я знаю, что в открытой сессии есть что-то подозрительное, но поверьте мне, для этого приложения это просто замечательно.Существует вероятность того, что приложение со временем станет портлетом, поэтому мне не хотелось обрабатывать проблемы с фильтрами портлетов и сервлетов.Вместо этого я хочу использовать удобные хуки, предоставляемые JSF, для открытия и закрытия слушателей фазы сеанса гибернации.К счастью, предоставляемый Spring OpenSessionInViewFilter раскрывает технические подробности того, как Spring работает с фабрикой сеансов гибернации.

Вот результат:

public class HibernateRestoreViewPhaseListener implements PhaseListener {
    public void afterPhase(PhaseEvent event) {
}

protected SessionFactory lookupSessionFactory() {
    FacesContext context = FacesContext.getCurrentInstance();
    ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
    WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    return (SessionFactory) wac.getBean("hibernate-session-factory", SessionFactory.class);
}

public void beforePhase(PhaseEvent event) {
    SessionFactory sessionFactory = lookupSessionFactory();
    if (!TransactionSynchronizationManager.hasResource(sessionFactory)) {
        Session session = getSession(sessionFactory);
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
    }
}

public PhaseId getPhaseId() {
    return PhaseId.RESTORE_VIEW;
}

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
    Session session = SessionFactoryUtils.getSession(sessionFactory, true);
    session.setFlushMode(FlushMode.MANUAL);
    return session;
}

Сессия закрываетсякогда фаза Render Response завершена:

public class HibernateRenderResponsePhaseListener implements PhaseListener {

    public void afterPhase(PhaseEvent event) {
        SessionFactory sessionFactory = lookupSessionFactory();
        SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
        closeSession(sessionHolder.getSession(), sessionFactory);
    }

    ...

}

Не забудьте зарегистрировать слушателей в face-config.xml

<lifecycle>
    <phase-listener>
        ...HibernateRestoreViewPhaseListener
    </phase-listener>
    <phase-listener>
        ...HibernateRenderResponsePhaseListener
    </phase-listener>
</lifecycle>
0 голосов
/ 16 июня 2011

настроили ли вы транзакцию?см http://justsomejavaguy.blogspot.com/2010/04/lazy-loading-under-spring.html

...