0

SpringアプリケーションでMySQLデータベースに接続しようとしています。DriverManager.getConnection(DB_URL,USER, PASS)Beanで構成されているdataSourceを使用しても接続できませんが、接続できます。

アプリのコンテキスト

<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest">
  <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
  <property name="username" value="xxxx"></property>
  <property name="password" value="xxxx"></property>
</bean>

クラス

public class JdbcTest {

  private DataSource dataSource;

  public JdbcTest(){
    try {
      Class.forName("com.mysql.jdbc.Driver");
      //conn = DriverManager.getConnection(DB_URL,USER,PASS); This worked!!!!
      conn = dataSource.getConnection(); 
      stmt = conn.createStatement();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

  public ResultSet executeQuery(String query){ 
        //executing query; it works as I tested with DriverManager
  }

  public static void main(String[] args) {  
    AbstractApplicationContext context = 
      new ClassPathXmlApplicationContext("spring.xml");
    JdbcTest test = context.getBean("jdbcTest", JdbcTest.class);
    ResultSet rs = test.executeQuery("select * from employee");
    try {
      while(rs.next()){
        System.out.println(rs.getString(1));
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

}

使用すると完全に正常に機能しましDriverManagerたが、DataSourceオブジェクトを使用してBeanで構成された接続を取得すると、次のようになります。NullPointerException

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTest' defined in class path resource [spring.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springdemo.jdbc.JdbcTest]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1011)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:957)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.springdemo.DrawingApp.main(DrawingApp.java:21)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springdemo.jdbc.JdbcTest]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1004)
    ... 13 more
Caused by: java.lang.NullPointerException
    at org.springdemo.jdbc.JdbcTest.<init>(JdbcTest.java:47)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
    ... 15 more
4

2 に答える 2

2

dataSourceコンストラクターではアクセスできません。Springは最初にBeanをインスタンス化し(この場合はデフォルトのコンストラクターを使用)、次にプロパティをワイヤリングします。

これに対処する方法はいくつかあります。

コンストラクター注入

<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest">
    <constructor-arg ref="dataSource"/>
</bean>

そしてクラス

public class JdbcTest {
    private DataSource dataSource;

    public JdbcTest(DataSource dataSource) throws SQLException {
        this.dataSource = dataSource;

        conn = dataSource.getConnection(); 
        stmt = conn.createStatement();
    }
}

InitializingBean

public class JdbcTest implements InitializingBean {
  private DataSource dataSource;

  // setter for dataSource

  public void afterPropertiesSet() {
      // run the actual test
      onn = dataSource.getConnection(); 
      stmt = conn.createStatement();
  }
}

Initメソッド

<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest" init-method="runTest">
  <property name="dataSource" ref="dataSource"/>
</bean>

そしてクラス

public class JdbcTest {
  private DataSource dataSource;

  // setter for dataSource

  public void runTest() {
      // run the actual test
  }
}
于 2013-02-01T22:52:04.770 に答える
1

Springによって注入されたデータソースを使用する場合、コンストラクターが呼び出されるまでデータソースは使用できません。基本的に、Springは、構成により、次のことを実行しています。

JdbcTest jdbcTest = new JdbcTest(); // NPE
jdbcTest.setDataSource(dataSource);

おそらくやりたいことは次のようなものです。

JdbcTest jdbcTest = new JdbcTest(dataSource);

これを行うには、構成を次のように更新します。

<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest">
    <constructor-arg ref="dataSource"/>
</bean>

そして、JdbcTestクラスは次のようになります。

public class JdbcTest {
    private DataSource dataSource;

    pubic JdbcTest(DataSource dataSource) throws SQLException {
        this.dataSource = dataSource;

        conn = dataSource.getConnection(); 
        stmt = conn.createStatement();
    }
}
于 2013-02-01T22:52:28.017 に答える