JSF 2、Spring、および Hibernate を使用してアプリケーションを構築しています。MyFaces Orchestra は、アプリケーションのほとんどのページで使用している会話スコープを提供するために使用されています (Hibernate セッションの Orchestra の管理を利用するため)。すべての Bean は conversation.access スコープを使用するように宣言されています。これは、(Orchestrator のドキュメントによると) ユーザーがそのバッキング Bean インスタンスへの参照を含まないページに移動するとすぐに、Bean がスコープから削除されることを意味するはずです。 .
私が遭遇している問題は、会話を明示的に無効にせずにビューから道をナビゲートした場合、後でそのビューに戻った場合でも、以前と同じデータが残っていることです。すべてのバッキング Bean に ConversationBindingListener メソッドを実装しましたが、それらがいつ会話から削除されるかを確認でき、多くの場合、そうではないことがわかります。
問題をさらに複雑にしているのは、一部のページ (ビュー) に移動するとバッキング Bean が削除され、他のページには移動しないことです。おそらく、EL 内の他のバッキング Bean への意図しない参照がページにあったためだと思いましたが、何も見つかりませんでした。また、この問題は、conversation.access スコープ Bean を持つ 1 つのページから、別の conversation.scoped Bean を使用する別のページに移動したときにのみ発生したのではないかと考えました。ただし、会話から削除された場合、そのページには conversation.access スコープ Bean への参照も含まれます。
先に述べたように、Conversation.getCurrentInstance().invalidate() を使用して会話を明示的に無効にすることは機能します。ただし、ユーザーがナビゲーション リンクの 1 つをクリックするだけでビューを離れることができるという非常に一般的なユース ケースであるため、すべてのユース ケースで会話を明示的に無効にすることはできません。
追加の詳細: Hibernate 3.6 (JPA の代わりに) を使用しているため、HibernatePersistenceContextFactoryを使用する必要がありました。
- MyFaces オーケストラ (myfaces-orchestra-core20-1.4.jar)
- JSF 2 (モハラ 2.0.4)
- スプリング 3.0
- プライムフェイス 2.2.1
- リッチフェイス 4.0.0
これが私の Spring コンテキスト構成の外観です (オーケストラの場合)。
<!-- 1. initialization of all orchestra modules (required for core15 module) -->
<import resource="classpath*:/META-INF/spring-orchestra-init.xml" />
<!-- 2. the conversation scopes -->
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="conversation.manual">
<bean
class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
<property name="timeout" value="30" />
<property name="advices">
<list>
<ref bean="persistentContextConversationInterceptor" />
</list>
</property>
</bean>
</entry>
<entry key="conversation.access">
<bean
class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
<property name="timeout" value="30" />
<property name="advices">
<list>
<ref bean="persistentContextConversationInterceptor" />
</list>
</property>
<property name="lifetime" value="access" />
</bean>
</entry>
</map>
</property>
</bean>
<!-- 3. the "entity manager" manager -->
<bean id="persistentContextConversationInterceptor"
class="org.apache.myfaces.orchestra.conversation.spring.PersistenceContextConversationInterceptor">
<property name="persistenceContextFactory" ref="persistentContextFactory" />
</bean>
<!-- 4. conversation - persistence adapter -->
<bean id="persistentContextFactory"
class="com.acme.infra.orchestra.hibernate.HibernatePersistenceContextFactory">
<property name="entityManagerFactory" ref="sessionFactory" />
</bean>
<!-- 5. persistence -->
<bean id="managedDataSource"
class="org.apache.myfaces.orchestra.connectionManager.ConnectionManagerDataSource">
<property name="dataSource" ref="dataSource" />
</bean>
JSF バッキング Bean 宣言の例をいくつか示します。
<bean id="quoteSummaryBackingBean" class="com.acme.ui.backing.QuoteSummaryBackingBean"
scope="conversation.access" orchestra:conversationName="QuoteSummaryConversation">
<property name="quotingBusinessService" ref="quotingBusinessService"/>
<property name="customerBusinessService" ref="customerBusinessService"/>
<property name="referenceDataBusinessService" ref="referenceDataBusinessService"/>
<property name="quoteExportBusinessService" ref="quoteExportBusinessService" />
</bean>
<bean id="createQuoteBackingBean" class="com.acme.ui.backing.CreateQuoteBackingBean"
scope="conversation.access" orchestra:conversationName="CreateQuoteConversation">
<property name="quotingBusinessService" ref="quotingBusinessService"/>
<property name="customerBusinessService" ref="customerBusinessService"/>
<property name="referenceDataBusinessService" ref="referenceDataBusinessService"/>