2017-06-07 9 views
2

私は、データベースに接続してデータを取得してレポートを生成する必要があるデスクトップアプリケーションで作業しています。テスト目的のために、必要なテーブルといくつかのダミーデータを含むDerbyのテストDBを作成しました。Apache Derbyを使用したJDBC throw java.sql.SQLNonTransientConnectionException:現在の接続なし

小さなアプリケーションであるため、軽量にするためにプレーンJDBCで作業することにしました。

開発用にTDDを使用しています。私はすでにファイルから接続プロパティをロードする方法と、DBへの接続を作成する方法をテストしました。データを照会し、そのデータにマップされたオブジェクトにデータを取り込もうとすると、私は立ち往生しました。これは私のコードです:

その後
public class JdbcManager { 

    static final String JDBC_DRIVER_PROPERTY = "jdbc.driver"; 
    static final String JDBC_URL_PROPERTY = "jdbc.url"; 
    static final String JDBC_USER_PROPERTY = "jdbc.username"; 
    static final String JDBC_PASSWORD_PROPERTY = "jdbc.password"; 
    static String PROPERTIES_FILE_PATH = "src/main/resources/connection.properties"; 
    String queryCareers = "SELECT career, name FROM db_career”; 

    private static final Logger LOG = Logger.getLogger(JdbcManager.class.getName()); 

    public List<Career> getCareerList() { 
     List<Career> result = new ArrayList<>(); 
     Career item; 
     Connection connection = createConnection(PROPERTIES_FILE_PATH); 
     try { 
      Statement stmt = connection.createStatement(); 
      ResultSet rs = stmt.executeQuery(queryCareers); 

      while (rs.next()) { 
       item = new Career(rs.getString("Career"), rs.getString("name")); 
       result.add(item); 
      } 
     } catch (SQLException ex) { 
      LOG.log(Level.SEVERE, “Error retrieving Career data”, ex); 
     } 

     return result; 
    } 

    // This method is working correctly according to my tests 
    Connection createConnection(String configFilePath) { 
     Properties connectionProperties = loadPropertiesFromFile(configFilePath); 
     try { 
      Class driverClass = Class.forName(connectionProperties.getProperty(JDBC_DRIVER_PROPERTY)); 
      LOG.log(Level.INFO, "Driver loaded: {0}", driverClass); 
     } catch (ClassNotFoundException ex) { 
      LOG.log(Level.SEVERE, "Driver not found”, ex); 
     } 

     try (Connection connection = DriverManager.getConnection(
       connectionProperties.getProperty(JDBC_URL_PROPERTY), 
       connectionProperties.getProperty(JDBC_USER_PROPERTY), 
       connectionProperties.getProperty(JDBC_PASSWORD_PROPERTY))) { 
      LOG.log(Level.INFO, “Connection created: {0}", connection); 
      return connection; 
     } catch (SQLException ex) { 
      LOG.log(Level.SEVERE, “Unable to connect to DB”, ex); 
      return null; 
     } 
    } 

    // This method is working correctly according to my tests 
    Properties loadPropertiesFromFile(String configFilePath) { 
     File configFile = new File(configFilePath); 
     Properties properties = new Properties(); 
     try { 
      properties.load(new FileInputStream(configFile)); 
      LOG.log(Level.INFO, “Properties loaded: {0}", properties); 
     } catch (FileNotFoundException ex) { 
      LOG.log(Level.SEVERE, "File not found", ex); 
     } catch (IOException ex) { 
      LOG.log(Level.SEVERE, "Error reading the file", ex); 
     } 

     return properties; 
    } 

} 

I失敗テストがあります。

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running ar.edu.unt.jdbc.JdbcManagerTest 
jun 06, 2017 7:57:24 PM ar.edu.unt.jdbc.JdbcManagerTest testGetCareerList 
INFO: testGetCareerList(): 
jun 06, 2017 7:57:24 PM ar.edu.unt.jdbc.JdbcManager loadPropertiesFromFile 
INFO: Properties loaded: {jdbc.url=jdbc:derby://localhost:1527/siu_test, jdbc.username=dba, jdbc.driver=org.apache.derby.jdbc.ClientDriver, jdbc.password=dba} 
jun 06, 2017 7:57:24 PM ar.edu.unt.jdbc.JdbcManager createConnection 
INFO: Driver loaded: class org.apache.derby.jdbc.ClientDriver 
jun 06, 2017 7:57:26 PM ar.edu.unt.jdbc.JdbcManager createConnection 
INFO: Connection created: [email protected] 
jun 06, 2017 7:57:26 PM ar.edu.unt.jdbc.JdbcManager getCareerList 
SEVERE: Error retrieving Career data 
java.sql.SQLNonTransientConnectionException: No current connection. 
    at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source) 
    at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source) 
    at org.apache.derby.client.am.Connection.createStatement(Unknown Source) 
    at ar.edu.unt.jdbc.JdbcManager.getCareerList(JdbcManager.java:49) 
    at ar.edu.unt.jdbc.JdbcManagerTest.testGetCareerList(JdbcManagerTest.java:71) 
    ... 

私はNetbeansのどこで働いている:私は、テストを実行したとき

@Test 
public void testGetCareerList() { 
    logger.log(Level.INFO, "testGetCareerList():"); 
    List<Career> expectedResult = Arrays.asList(
      new Career("LGU", “Some dummy name 1”), 
      new Career("TSGU", "Some dummy name 2”)); 

    // Change the location of the properties file to the testing one 
    GestorJdbc.PROPERTIES_FILE_PATH = "src/test/resources/connectionTest.properties"; 

    List<Career> actualResult = jdbcManager.getCareerList(); 
    assertEquals(expectedResult, actualResult); 
} 

そして最後にスタックトレースを私はどこに接続することができます(私が言ったように、接続が正常に動作している)実行中のDerby DBを持っています。 stacktraceで見ることができるように、例外はcreateStatement()にスローされますが、理由を見つけることができません。

私はブログや投稿でダイビングしてきましたが、何も私のために働いていませんでした。ユーザーがThread.isInterrupted()を呼び出すことによって問題を解決した投稿がありましたが、createStatement()は同期されていますが、私のアプリケーション全体に1つのスレッドを使用しているため、私にとってはうまくいきませんでした(実際は古い投稿メソッドがJava 8で利用できないように思われるので、Thread.interrupted()というような類似のメソッド)。

私のアプリケーションに関する詳細情報が必要な場合は、あなたのコメントでお知らせください。いかなる助けや指導も感謝します。

答えて

1

あなたのメソッドcreateConnectionは閉じた接続を返しています。 try-with-resourcesステートメントを使用して接続を作成しています。つまり、この接続は、ブロックの終了時に自動的に閉じられます(例外的に、ブロックまたはブロックの終了によって例外が発生します)。

その後、ステートメントを作成しようとすると、ドライバは接続していないことを報告します(エラーメッセージ自体はもう少し明確になります)。ところで

Connection createConnection(String configFilePath) { 
    Properties connectionProperties = loadPropertiesFromFile(configFilePath); 
    try { 
     Class driverClass = Class.forName(connectionProperties.getProperty(JDBC_DRIVER_PROPERTY)); 
     LOG.log(Level.INFO, "Driver loaded: {0}", driverClass); 
    } catch (ClassNotFoundException ex) { 
     LOG.log(Level.SEVERE, "Driver not found”, ex); 
    } 

    try { 
     Connection connection = DriverManager.getConnection(
      connectionProperties.getProperty(JDBC_URL_PROPERTY), 
      connectionProperties.getProperty(JDBC_USER_PROPERTY), 
      connectionProperties.getProperty(JDBC_PASSWORD_PROPERTY)) 
     LOG.log(Level.INFO, “Connection created: {0}", connection); 
     return connection; 
    } catch (SQLException ex) { 
     LOG.log(Level.SEVERE, “Unable to connect to DB”, ex); 
     return null; 
    } 
} 

:要するに

、あなたはにcreateConnectionを変更する必要があり、例外でnullを返すには、本当に他の場所でNullPointerExceptionを求めています。 SQLExceptionを投げたり、独自の例外を作成したりしてみてください。

あなたがすべきながら、あなたはcreateConnectionに問題を修正したら、あなたはgetCareerListでそれらを正しく閉じていないことにより、リソースをリークされるため、一方、getCareerListであなたは、試し-とリソースを使用していません。

try (Connection connection = createConnection(PROPERTIES_FILE_PATH); 
    Statement stmt = connection.createStatement(); 
    ResultSet rs = stmt.executeQuery(queryCareers)) { 

    //... rest 
} catch (SQLException e) { 
    //... rest 
} 

結果セット、ステートメント、および接続は、常に正しく閉じられます。

+0

ありがとう、それは最後に論理的な誤りだった(かなり明白な、私の上の恥ずべき) –

関連する問題