2

Spring 3.1.1 から 3.2.6 に更新しました

3.1 では、次のコードがうまく機能しました。

@Bean(name = DEMO_DS)
public JndiObjectFactoryBean demoDataSource()
{
    JndiObjectFactoryBean factory = new JndiObjectFactoryBean();
    factory.setJndiName(JDBC_DEMO_DS);
    factory.setProxyInterface(DataSource.class);
    return factory;
}

@Bean(name = DEMO_SESSION_FACTORY)
public SqlSessionFactoryBean demoSqlSessionFactory(@Qualifier(DEMO_DS) DataSource dataSource)
{
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    sessionFactory.setConfigLocation(new ClassPathResource("demo/config.xml"));

    return sessionFactory;
}

ただし、アップグレードされたバージョンでは、次の例外が発生します。

原因: org.springframework.beans.factory.NoSuchBeanDefinitionException: 依存関係に該当するタイプ [javax.sql.DataSource] の Bean が見つかりません: この依存関係のオートワイヤー候補として適格な Bean が少なくとも 1 つ必要です。依存アノテーション: {@org.springframework.beans.factory.annotation.Qualifier(value=DemoDataSource)}

複数の DataSources があるため、 @Qualifier が必要です。

ありがとう。

編集:

これで問題が解決したようです:

public DataSource dataSourceFactory() {
    try
    {
        return (DataSource) demoDataSource().getObject();
    }
    catch (Exception ex)
    {
        throw new RuntimeException(ex);
    }
}

...

sessionFactory.setDataSource(dataSourceFactory());

しかし、私はそれが良い解決策だとは思いません。

4

1 に答える 1

0

必要に応じて、構成を少し書き直してください。注入されたデータソースが本当に必要ない場合は、次のようなことができます。

@Bean(name = DEMO_DS)
public JndiObjectFactoryBean demoDataSource() {
    JndiObjectFactoryBean factory = new JndiObjectFactoryBean();
    factory.setJndiName(JDBC_DEMO_DS);
    factory.setProxyInterface(DataSource.class);
    return factory;
}

@Bean(name = DEMO_SESSION_FACTORY)
public SqlSessionFactoryBean demoSqlSessionFactory() {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(demoDataSource().getObject());
    sessionFactory.setConfigLocation(new ClassPathResource("demo/config.xml"));
    return sessionFactory;
}

データソースを注入する必要がある場合はJndiLocatorDelegate、 の代わりに を使用してルックアップを行うように切り替えることができますJndiObjectFactoryBean

@Bean(name = DEMO_DS)
public DataSource demoDataSource() throws NamingException {
    return JndiLocatorDelegate.createDefaultResourceRefLocator().lookup(JDBC_DEMO_DS, DataSource.class);
}

これにより、おそらく問題の原因である(これが何であるか)のDataSource代わりに直接提供されます。FactoryBean<Object>JndiObjctFactoryBean

@Valueまたは(理論的には)構成クラスのプロパティで注釈を使用できるはずです。@Value通常の代わりに@Resource、トリックも実行する必要があります(ルックアップのためにJNDIへの呼び出しを委任することもできます)。

public class MyConfig {

    @Value("${" + JDBC_DEMO_DS + "}")
    private DataSource demoDs;

}

@Resource

public class MyConfig {

    @Resource(mappedName=JDBC_DEMO_DS)
    private DataSource demoDs;

}

そして、構成メソッドでそれを参照するだけです。

@Bean(name = DEMO_SESSION_FACTORY)
public SqlSessionFactoryBean demoSqlSessionFactory() {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(demoDs);
    sessionFactory.setConfigLocation(new ClassPathResource("demo/config.xml"));
    return sessionFactory;
}
于 2013-12-17T11:22:01.903 に答える