2013-01-02 39 views
1

基本上,我從數據庫中獲取ResultSet時遇到了問題。 (?)約34號線在此代碼塊中出現的錯誤,但我已經將其標記查詢時出現MySQL MySQL NullPointerException

ResultSet rs = caq.executeQuery("SELECT * FROM ProjectScore"); //error goes here 

我得到運行時一個空指針異常,這是從下面的catch語句輸出:

null, calculating average score failed 

java.lang.NullPointerException 

[Ljava.lang.StackTraceElement;@1de2b1 

有趣的是,我使用連接完全相同的類在最後,我沒有收到任何錯誤。將語句複製到第一個類別也不起作用,所以我認爲它是別的。我想這就是我的全部,任何幫助表示讚賞:)

import java.awt.*; 
import java.awt.event.*; 
import java.sql.*; 

import javax.swing.*; 

public class MainWindow extends JFrame implements ActionListener{ 
    //....................... 
    private int [] averageScore; 

    //References 
    private LogInWindow liw; 
    private NewUserWindow nuw; 
    private ScoreWindow sw; 
    private boolean isAnotherWindowOpen = false; 
    private boolean isLoggedIn = false; 
    private ConnectionAndQueries caq; 

    public MainWindow(ConnectionAndQueries caq) throws SQLException{ 
     this.caq = caq; 

     //................................. 

     //Middle 
     averageScore = new int [9]; 
     calculateAverageScore(); 
     setTable(); 

     //............................ 
    } 

    private void calculateAverageScore() throws SQLException{ 
     try{ 
      ResultSet rs = caq.executeQuery("SELECT * FROM ProjectScore"); //error goes here 
      int [] count = new int [9]; 
      int [] totalScore = new int [9]; 

      while(rs.next()){ 
       int itemID = rs.getInt("itemID"); 

       count[itemID]++; 
       totalScore[itemID] += rs.getInt("Score"); 
      } 

      for(int i = 0; i < 9; i++){ 
       averageScore[i] = totalScore[i]/count[i]; 
      } 
     } 
     catch (Exception e) { 
      System.out.print(e.getMessage()); 
      System.out.println(", calculating average score failed"); 
      System.out.println(e.toString()); 
      System.out.println(e.getStackTrace().toString()); 
     } 
    } 
} 




//next class 

import java.sql.*; 

public class ConnectionAndQueries { 
    private static Connection connection; 
    private static Statement statement; 
    private MainWindow mw; 

    public ConnectionAndQueries() throws ClassNotFoundException, SQLException{ 
     mw = new MainWindow(this); 
     connect(); 
    } 

    public static void connect() throws ClassNotFoundException, SQLException{ 
     try{ 
      Class.forName("com.mysql.jdbc.Driver"); 
      connection = DriverManager.getConnection("jdbc:mysql://zzzzzzzzzz", "yyyy",  "xxxx"); //dont think im allowed to give that info 
      statement = connection.createStatement(); 
     } catch (Exception e) { 
      System.out.println("Connecting to the database failed"); 
     } 
    } 

    public ResultSet executeQuery(String query) throws SQLException { 
     return statement.executeQuery(query); 
    } 

    public int executeUpdate(String update) throws SQLException { 
      return statement.executeUpdate(update); 
    } 

    public static void main(String [] args) throws ClassNotFoundException, SQLException{ 
     ConnectionAndQueries caq = new ConnectionAndQueries(); 
    } 
} 




//another class which uses the connection class, and works. 

import java.awt.*; 
import java.awt.event.*; 
import java.sql.*; 

import javax.swing.*; 

public class LogInWindow extends JFrame implements ActionListener{ 
    //........................ 

    //References 
    private MainWindow mw; 
    private ConnectionAndQueries caq; 

    public LogInWindow(MainWindow mw, ConnectionAndQueries caq){ 
     this.mw = mw; 
     this.caq = caq; 

     //...................... 
    } 

    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == logIn){ 
      String usn = usernameField.getText(); 
      String pwd = passwordField.getText(); 

      try { 
       ResultSet rs = caq.executeQuery("SELECT * FROM ProjectCustomer"); 

       while(rs.next()){ 
        if(rs.getString("username").equals(usn)){ 
         if(rs.getString("passwrd").equals(pwd)){ 
          logInSuccess(usn); 
          mw.userLoggedIn(usn); 
          quit(); 
         } 
        } 
       } 

       if(mw.isUserLoggedIn() == false) 
        logInFailed(); 

      } catch (Exception e2) { 
       System.out.print(e2.getMessage()); 
       System.out.println(", error at log in"); 
       System.out.println(e2.toString()); 
      } 
     } 

     else if(e.getSource() == quit){ 
      quit(); 
     } 
    } 

    //............................ 
} 

回答

3

當調用此構造函數時,它將自身的引用發送給MainWindow。

public ConnectionAndQueries() throws ClassNotFoundException, SQLException{ 
    mw = new MainWindow(this); 
    connect(); 
} 

然而,如在被引用的對象還沒有被構造發送該參考(即,構造尚未結束)的基準只能爲空在這一點上。

解決這個問題的一種方法是將代碼從構造函數移動到主要方法,在下新的ConnectionAndQueries()。不過,我強烈建議重構程序結構以將數據庫連接和操作分離爲一個或多個單獨的類,並將UI代碼與數據庫代碼解耦。

+0

是的,這是問題,可惜我不能做所有這些修復,因爲我不允許改變程序結構:( – Latedi

1

看起來你ConnectionAndQuery對象爲null。

我會在施工時檢查這是否爲空,而不是當你嘗試和使用它。這將更早地捕獲錯誤(並且在更有用的時間)。也有可能(因爲錯誤報告是不明確的 - 見下文),這:

catch (Exception e) { 
    System.out.println("Connecting to the database failed"); 
} 

正在捕獲錯誤,但留下未初始化語句對象(空)。我會檢查語句的無效性作爲先決條件,或者更好地拋出原始異常,以便客戶機代碼必須處理損壞的ConnectionAndQuery對象。

System.out.println(e.getStackTrace().toString()); 

是不是非常有幫助,順便說一句。我寧願做:

e.printStackTrace(); 

,因爲它會轉儲完整的堆棧跟蹤,並轉儲到stderr(錯誤常規目的地)。目前,您在棧幀數組上調用toString(),這並沒有什麼實用價值。

+0

事實上,即使在this.caq = caq處指定對象後,對象也是空的。在構造函數中。但是我使用相同的變量來稍後給出另一個類的引用? – Latedi

+0

你的'MainWindow'構造函數在'connect()'之前被調用,我認爲是正確的? –

+1

嗯,我不認爲語句或對象可以爲空,因爲它們稍後會被使用,工作完好。打印的stacktrace並沒有真正給出任何線索,我認爲excepet也許這行:return statement.executeQuery(query);在ConnectionAndQueries類中。我也把這個:\t \t this.caq = caq; \t \t System.out.println(caq);在構造函數中,我收到ConnectionAndQueries @ 103c0ad,所以它似乎不是null? – Latedi

2

問題是因爲構造函數。

公共ConnectionAndQueries()拋出ClassNotFoundException的,的SQLException {

MW =新主窗口(本);

connect();

}

在這裏從主窗口,其makding呼叫calculateAverageScore,其執行與ConnectionAndQueries查詢的構造函數。由於connect()目前尚未調用,因此連接和語句爲空。所以得到空指針異常。

嘗試,在mw = new MainWindow(this)前調用connect()。聲明。

公共ConnectionAndQueries()拋出ClassNotFoundException的,的SQLException {

連接();

mw = new MainWindow(this);

}

但可以肯定的代碼重構由Gorkamorka的建議是必需的。

+0

是這是我所做的,它的工作:) ...這是一個更正確的答案?或者我應該離開它? – Latedi