2013-02-01 100 views
0

我試圖在我的spring應用程序中連接到MySQL數據庫。如果使用DriverManager.getConnection(DB_URL,USER,PASS),但無法與使用bean配置的dataSource建立連接,則可以進行連接。dataSource.getConnection在Spring中拋出NullpointerException

應用方面

<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; 
     pubic JdbcTest(){ 
     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的,但是,當我用數據源對象,以獲取其配置與豆連接它的工作完全沒有問題,它給人的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 

回答

2

您無法訪問dataSource e構造函數。 Spring首先實例化這個bean(在你的情況下使用默認構造函數),然後連接這些屬性。

a number of ways來處理。

構造方法注入

<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 
    } 
} 
1

當使用由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(); 
    } 
} 
+0

@Marcel和Rob ..非常感謝你。 – mik

相關問題