3

Spring 3.0.2、hibernate3、およびjsf2を使用して、OpenSessionInViewFilterを機能させるのに大きな問題があります。

シナリオ:

いくつかの単純な情報プロパティ (string および int タイプ) とマップされた EmployeeEntities のリストを保持する BusinessCaseEntity があります。このリストは

fetch=FetchType.LAZY

まず、すべての BusinessCases のリストを読み込み、表に表示します。この目的のために、dao クラスを使用します。シンプルなプロパティを持つビジネスケースが表示されます。特定のビジネスケースを選択した場合、たとえば接続されている従業員を表示したいとします。したがって、ビジネスケース オブジェクトの getter メソッドを使用したいだけです --> getEmployees()

春と休止状態についての私の単純な理解では、この時点で BusinessCaseEntity がバックエンドで任意の春と休止状態 (セッション) から切り離され、有名な LazyLoadingException が表示されることがわかります。

これは、OpenSessionInViewFilter が配置されると私が思うところです。私はそれを使用する方法の多くの指示を読みましたが、それでも自分のアプリで動作させることができませんでした.

私のweb.xmlでフィルターを構成し、Springの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 の目的を誤解していますか?

私は今かなり迷っており、本当に助けていただければ幸いです。

ありがとう - クリス

4

2 に答える 2

1

Spring の OpenSessionInViewFilter を使用することをあきらめました。ここで方向付​​けられているように、私は仕事をするために JSF フェーズ リスナーを実装しました: http://assenkolov.blogspot.com.br/2008/04/open-session-in-view-with-jsf-and.html。解決策は私にとってはうまくいきました。

以下の完全な投稿 (リンクが無効になっている場合):

Google で簡単にセッションを行えば、この状況に対する標準的な解決策がすぐに見つかると思っていましたが、そうはなりませんでした。

問題: JSF/Spring アプリケーションの View で Open Session が必要です。わかりました。オープン セッションについて怪しいものがあることは承知していますが、信じてください。このアプリケーションでは、これで問題ありません。アプリケーションが最終的にポートレットになる可能性があるため、ポートレットとサーブレット フィルターの問題も処理する必要はありませんでした。代わりに、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);
    }

    ...

}

リスナーをfaces-config.xmlに登録することを忘れないでください

<lifecycle>
    <phase-listener>
        ...HibernateRestoreViewPhaseListener
    </phase-listener>
    <phase-listener>
        ...HibernateRenderResponsePhaseListener
    </phase-listener>
</lifecycle>
于 2014-06-30T19:12:31.017 に答える
0

トランザクションを設定しましたか? http://justsomejavaguy.blogspot.com/2010/04/lazy-loading-under-spring.htmlを参照してください。

于 2011-06-16T19:08:24.227 に答える