Struts2、Spring、および Hibernate を使用して、マルチデータソース Web ポータルに取り組んでいます。アプリケーションの起動時ではなく、ユーザーのログイン時に使用できるユーザー資格情報をデータ ソースの 1 つに設定する際に問題があります。最初のポータル ユーザーには機能しますが、後続のすべてのユーザーには失敗します。
データ ソースごとにセッション ファクトリが作成され、Spring 構成を介して基になるデータソース セットが取得されます。
私の 4 つのデータ ソースのうち 3 つは、構成によって設定されたデータベース ログイン資格情報を取得しますが、1 つはポータル ユーザーの資格情報を使用する必要があります。私のBeanはセッションスコープにあることに注意してください。
これが私のデータソース構成です:
<!-- data source with credentials from configuration -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="session">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- data source that authenticates with user credentials from login. -->
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="session">
<property name="driverClassName" value="${ds2.jdbc.driverClassName}" />
<property name="url" value="${ds2.jdbc.url}" />
</bean>
これが私のセッションファクトリ構成です:
<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" scope="session">
<property name="dataSource">
<ref bean="dataSource1" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
...
</props>
</property>
<property name="mappingResources">
<list>
<value>hibernate/AnotherDTO.hbm.xml</value>
...
</list>
</property>
</bean>
<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" scope="session">
<property name="dataSource">
<ref bean="dataSource2" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
...
</props>
</property>
<property name="mappingResources">
<list>
<value>hibernate/MyDTO.hbm.xml</value>
...
</list>
</property>
</bean>
ポータル ユーザーのユーザー名とパスワードは、ポータルへのログインが成功した後にのみ使用できるため、プログラムでデータ ソースの 1 つ (dataSource2) に設定する必要があります。
これを実現するには、Spring にデータ ソースをログイン アクション (Struts2) に挿入させ、提供されたセッター メソッドを使用して、ログインのたびにデータ ソースでユーザー名とパスワードを設定します。
@Qualifier("dataSource2")
private DriverManagerDataSource dataSource2;
private void postAuthenticate() {
dataSource2.setUsername(user);
dataSource2.setPassword(password);
}
私の DAO は、コンストラクターに挿入されたセッション ファクトリを取得し、それを HibernateDaoSupport に渡します (はい、私は HibernateTemplate を使用しています。彼の時点でそれについて議論しないでください ;-) ):
public class MyDAO extends HibernateDaoSupport {
@Autowired
public MyDAO(@Qualifier("sessionFactory2") SessionFactory pSessionFactory) {
setSessionFactory(pSessionFactory);
}
...
}
これで、ポータルを使用する最初のユーザーは問題なく動作します。ポータルの開始ページに、dataSource2 を使用する DAO からのアイテムのリストが表示されます。ただし、ポータルにログインしている次のすべてのユーザーは、dataSource2 から結果を取得しません。例外は発生せず、ログ メッセージも発生しません。これは、データベースへの有効な接続があり、他のユーザーの資格情報のみを使用している (したがって、2 番目のユーザーに適切な結果が返されない) ためです。
私の仮定は、Hibernate または Spring が何らかの形で前のユーザーのセッション ファクトリから古い接続を破棄せずに使用し続けるか、新しいデータ ソースに設定した新しい資格情報を無視することです。
私の問題に対する洞察や役立つヒント (または解決策!) を提供してくれる人はいますか? アプリケーションの起動時に利用できないが、ユーザーのログイン時に利用できないユーザー資格情報を持つデータ ソースを使用するのは本当に難しいのでしょうか。 )。
どうもありがとうございました。