2010-08-11 5 views
0

Je suis Java débutant, mais je pensais que lors de l'utilisation try-catch-finally Je n'ai pas de déclarer l'exception en utilisant throws SQLException. Toutefois, si je ne l'utilise pas le compilateur me donne l'erreur:try-catch-finally jeter exception problème Java

"unreported exception java.sql.SQLException; must be caught or declare to be thrown".

J'inclus un hic donc je ne sais pas pourquoi cette erreur se produit.

public static ResultSet getResultSet (String query) 
{ 
    dbConn = getConnection(); 

    try 
    { 
     stmt = dbConn.createStatement(); 

     ResultSet rs = stmt.executeQuery(query); 

     return rs; 
    } 
    catch (SQLException ex) 
    { 
     return null; 
    } 
    finally 
    { 
     stmt.close(); 
     dbConn.close(); 
    } 
} 
+5

Aide, beaucoup de matrices de chatons. Vous avez déclaré 'dbConn' et' stmt' comme 'static'. Ce code n'est définitivement pas sécurisé. Je recommande fortement de refaire les tutoriels Java et JDBC de base. – BalusC

+1

Vous obtiendrez également 'SQLExceptions' lorsque vous utiliserez' ResultSet', donc vous pourriez propager l'exception. Le 'ResultSet' ne fonctionnera probablement pas après la fermeture de la connexion. Vous pourriez envisager l'idiome Execute Around. http://stackoverflow.com/questions/341971/what-is-the-execute-around-idiom –

+1

FWIW: la pratique * normal * consiste à mapper le 'ResultSet' sur une' Liste 'et de le retourner à la place. Pour quelques exemples, [head here] (http://stackoverflow.com/questions/3148092/java-jdbc-mysql-connector-how-to-resolve-disconnection-after-a-long-idle-time/3148857#3148857) et [ici] (http://stackoverflow.com/questions/1813858/sqlite-3-jdbc-driver-throws-resultsset-closed-exception-on-empty-resultset/1814443#1814443). – BalusC

Répondre

9

Il est parce que les méthodes close():

stmt.close(); 
dbConn.close(); 

peut jeter SQLException et vous ne les avez pas encapsulé dans un bloc try/catch.

Une méthode peut très bien lancer une exception à l'intérieur d'un article enfin, et, sans la manutention des prises clause de ces exceptions, la méthode doit être déclarée à jeter ces exceptions.

Fondamentalement, vous devez faire quelque chose comme

finally 
{ 
    try { 
     stmt.close(); 
    } catch (SQLException sqle) { 
     // log the statement-close exception 
    } 

    try { 
     dbConn.close(); 
    } catch (SQLException sqle) { 
     // log the connection-close exception 
    } 
} 
+2

Non, fondamentalement, vous devez mettre chaque 'close()' dans ** son propre '' try-catch' qui enregistre ou ignore l'exception. close() 'throws, alors' dbConn.close() 'n'aura jamais lieu – BalusC

+0

ah, bon point Je mettrai à jour :) – aioobe

+2

Vous pouvez aussi ajouter nullchecks. – BalusC

4

Mettez dbConn = getConnection(); dans la section try. It can throw an SQLException too.

+0

Cela semble une autre méthode statique du cru. Il a peut-être déjà supprimé cette exception à l'intérieur de la méthode (ce qui est en fait une mauvaise idée). – BalusC

2

Outre les erreurs du compilateur, ce code échouera lors de l'exécution.

Lorsque vous fermez le Connection à partir duquel le ResultSet est créé, le ResultSet est invalidé et tous les appels échouent. (Bien sûr, certains pilote JDBC étrange être mis en œuvre pour que cela pourrait fonctionner, mais cela est une mauvaise utilisation de l'API JDBC.)

La portée et la durée de vie du ResultSet ne peut pas être une plus large que son parent Connection et Statement.

0

Le code que vous avez écrit utilise une classe qui a un type d'exception à gérer. Vous pouvez le faire de deux façons, en le faisant passer par la chaîne, c'est-à-dire en relançant l'exception, ou en la manipulant comme le montrent les autres commentaires en plaçant les méthodes de fermeture dans un try catch bloc.

En général, vous verrez ces fichiers dans les classes IO où vous devez toujours fermer l'objet ou d'un ruisseau pour vous assurer le laisser dans un état valide. Sinon, vous le laissez au système d'exploitation pour nettoyer pour vous.