IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Exception ResultSet Closed


Sujet :

JDBC Java

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut Exception ResultSet Closed
    Bonjour à tous.

    Alors voilà je dois développer une application utilisant JDBC. Jusqu'ici tout se passait bien j'enchainais les requêtes avec zèle, jusqu'à ce qu'une requête me sorte ResultSet Closed en SQLException. J'ai beau chercher je ne vois pas le problème. Ma requête est censé me retourner un objet de type Equipement mais pas moyen. J'ai vérifié les données de ma BDD et celle demandées correspondent.
    En exécutant directement la requête dans le SGBD, j'obtiens bien le résultat souhaité. Ce qu'il faut savoir c'est que la requête ne peut retourner uniquement 1 ou 0 résultat.

    Voici le code minimal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    public class SQLite {
     
    	String database;
    	Connection connection;
    	Statement statement;
    	ResultSet resultat;
     
    	public SQLite(String database) {
    		this.database = database;
     
    		try {
    			//Chargement du driver JDBC
    			Class.forName("org.sqlite.JDBC");
     
    			//Connexion à la base de données
    			String     url = "jdbc:sqlite:" + database;
    			connection = DriverManager.getConnection(url);
     
    		} catch (SQLException ex) {
    		    Logger.getLogger(SQLite.class.getName()).log(Level.SEVERE, null, ex);
    		} catch (ClassNotFoundException ex) {
    		    Logger.getLogger(SQLite.class.getName()).log(Level.SEVERE, null, ex);
    		}
    	}
     
    	public ResultSet executerRequete(String requete) {
    		resultat = null;
    		try {
    			statement = connection.createStatement();
    			resultat = statement.executeQuery(requete);
    		} catch(SQLException e) {
    			Logger.getLogger(SQLite.class.getName()).log(Level.SEVERE, null, e);
    		}
    		return resultat;
    	}
     
    //ici que ça foire au moment de récupérer avec getInt()
    	public Equipement donnerEquipement(String nomEquipement) {
    		System.out.println("test entrée");
    		Equipement sortie = null;
    		try {
    			ResultSet resultat = executerRequete("SELECT * FROM Equipements WHERE nom = '" + nomEquipement + "'");
    			int id = resultat.getInt("id");
    			String code = resultat.getString("code");
    			int idProduit = resultat.getInt("idProduit");
    			String nom = resultat.getString("nom");
    			String libelle = resultat.getString("libelle");
    			String image = resultat.getString("image");
    			sortie = new Equipement(id, code, idProduit, nom, libelle, image);
    		} catch(SQLException e) {
    			e.printStackTrace();
    		}
    		return sortie;
    	}
    }
    Mes autres requêtes sur le même schéma fonctionnent sans problème pourtant.

    Quelqu'un à une idée ?
    Merci d'avance

  2. #2
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    sqlite ferme automatiquement le resultset une fois qu'il à été parcourcu. Il convient de repasser une requête pour une seconde utilisation.

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Je ne comprends pas ce que tu veux dire par repasser une seconde requête pour une seconde utilisation.
    Ma fonction executerRequete() n'exécute t'elle pas une nouvelle requête à chaque fois ?

  4. #4
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    je ne dis pas le contraire. Je commente simplement le type d'erreur. Par ailleurs qui me dit que l'erreur est liée au executeMachin ???
    Le stack trace ?

    Le reste du code.

    Bref en l'état impossible de se prononcer.

  5. #5
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Voici le stackTrace lorsque je tente d'appeler la fonction donnerEquipement(String). Après des tests cela se produit au moment ou je tente d'accéder à un attribut avec getInt() par exemple.

    java.sql.SQLException: ResultSet closed
    at org.sqlite.RS.checkOpen(RS.java:57)
    at org.sqlite.RS.findColumn(RS.java:103)
    at org.sqlite.RS.getInt(RS.java:232)
    at JDBC.SQLite.donnerEquipement(SQLite.java:126)
    at ListeEquipementListener.actionPerformed(ListeEquipementListener.java:39)
    at javax.swing.JComboBox.fireActionEvent(Unknown Source)
    at javax.swing.JComboBox.setSelectedItem(Unknown Source)
    at javax.swing.JComboBox.setSelectedIndex(Unknown Source)
    at javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(Unknown Source)
    at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at javax.swing.plaf.basic.BasicComboPopup$1.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

    Sinon j'ai d'autres requètes sur le même schéma qui elles fonctionnent à la perfection :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    	public Produit donnerProduit(String nomProduit) {
    		Produit sortie = null;
    		try {
    			ResultSet resultat = executerRequete("SELECT * FROM Produits WHERE nomProduit = '" + nomProduit + "'");
    			int id = resultat.getInt("id");
    			String code = resultat.getString("code");
    			int modele = resultat.getInt("modele");
    			String nom = resultat.getString("nomProduit");
    			String libelle = resultat.getString("libelle");
    			String image = resultat.getString("image");
    			sortie = new Produit(id, code, modele, nom, libelle, image);
    		} catch(SQLException e) {
    			e.printStackTrace();
    		}
    		return sortie;
    	}
    Merci d'avoir pris du temps pour essayer de m'aider.

  6. #6
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    at JDBC.SQLite.donnerEquipement(SQLite.java:126)

    c'est quoi la ligne 126

    remplacer le nom du champs par son numéro de colonne pour voir.

  7. #7
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Ma ligne 126 correspond à :
    int id = resultat.getInt("id");

    En remplaçant par le numéro de colonne le problème reste le même malheureusement.

  8. #8
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    la requete n'est probablement pas bonne ou vide.
    il faut vérifier le resultSet.

    il faut passer la requete en dur pour debugger.

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    je vois deux erreurs principales dans votre code:

    1) quand on a fini d'utiliser un resultset, il faut TOUJOURS appeler close() dessus! Le faire dans un bloc finally pour etre sur que le code est exécuté
    2) avant de lire les données sur la première ligne d'un resultset, il faut toujours appeler next(), qui retournera true ou false suivant qu'il y a une nouvelle ligne disponible. Par défaut, lors de sa création, le resultset est toujours positionnée avant la première ligne.

  10. #10
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Merci de vous intéresser à mon problème.

    1) Ma requête me fournit bien un résultat lorsque je la teste directement dans le SGBD, donc exécuter la même requête SELECT à partir de JDBC devrait me fournir un résultat.

    2) Concernant le next() je l'utilisais à la base mais cela n'ayant pas changé le problème je l'ai retiré. Je vais donc le remettre vu qu'il semble nécessaire.

    3) Oki pour le close() je n'y avais pas pensé. En quoi cela est il obligatoire? La méthode n'est pas appelé automatiquement à la destruction de l'objet?

    En essayant de faire un if(resultat.next()) j'obtiens toujours false.

    J'ai testé d'ajouter vos modifications malgré tout il n'y a pas de changement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public Equipement donnerEquipement(String nomEquipement) {
    		System.out.println("test entrée");
    		Equipement sortie = null;
    		try {
    			statement = connection.createStatement();
    			resultat = statement.executeQuery("SELECT * FROM Equipements WHERE nom = 'Contrôle de Flux Fertimax'");
    			resultat.next();
    			int id = resultat.getInt(0);
    			String code = resultat.getString("code");
    			int idProduit = resultat.getInt("idProduit");
    			String nom = resultat.getString("nom");
    			String libelle = resultat.getString("libelle");
    			String image = resultat.getString("image");
    			sortie = new Equipement(id, code, idProduit, nom, libelle, image);
    			resultat.close();
    		} catch(SQLException e) {
    			e.printStackTrace();
    		}
    		return sortie;
    	}

  11. #11
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    il me semble qu'il n'y a pas de colonne 0 sur un resultset la premiere colonne commence à 1

  12. #12
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    J'ai essayé avec 0, 1 et "id"(le nom de la colonne), le problème persiste.
    Java continue à m'insulter copieusement à coup de Result Set Closed.

    java.sql.SQLException: ResultSet closed
    at org.sqlite.RS.checkOpen(RS.java:57)
    at org.sqlite.RS.markCol(RS.java:71)
    at org.sqlite.RS.getInt(RS.java:230)
    at JDBC.SQLite.donnerEquipement(SQLite.java:132)
    at FenetrePrincipale.initialiseListeEquipements(FenetrePrincipale.java:246)
    at FenetrePrincipale.initialiseComposants(FenetrePrincipale.java:86)
    at FenetrePrincipale.<init>(FenetrePrincipale.java:66)
    at Application.main(Application.java:41)

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Citation Envoyé par vince85 Voir le message

    3) Oki pour le close() je n'y avais pas pensé. En quoi cela est il obligatoire? La méthode n'est pas appelé automatiquement à la destruction de l'objet?
    C'est comme les fichies, si vous ne le faites pas manuellement, ce ne sera fermé que lorsque vous quitterez l'applicaiton. en attendant ca occupera de la mémoire et des ressources dans la DB.
    Citation Envoyé par vince85 Voir le message
    En essayant de faire un if(resultat.next()) j'obtiens toujours false.
    Il n'y a donc pas de résultat à votre requete, vous ne pourrez rien lire. Ce qui explique le closed, Certain drivrs ferment automatiquement le resultSet quand il n'y a plus rien à lire.

  14. #14
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    faudrait tester ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM Equipements LIMIT 10"
    pour voir. il peut y avoir un doute sur le 'Contrôle'. notamment le 'ô'

  15. #15
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Il n'y a donc pas de résultat à votre requete, vous ne pourrez rien lire. Ce qui explique le closed, Certain drivrs ferment automatiquement le resultSet quand il n'y a plus rien à lire.
    Y a t'il une manipulation à faire avec sqlite dans ce cas ?
    En essayant d'exécuter directement cette requète dans la BDD voici le résultat
    (SELECT * FROM Equipements WHERE nom = 'Contrôle de Flux Fertimax')
    me donne :
    1 1 FMX Contrôle de Flux Fertimax Un super contrôle de flux Fertimax !!! NULL

    Existe t'il un moyen de connaître le type d'un objet ou son contenu pour réaliser un débug en Java?

    Est ce possible qu'une même requête exécutée sur une même base de données avec JDBC et directement dans le SGBD donne un résultat différent?

    J'avoue que je commence à désespérer un peu

  16. #16
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    En réalisant un SELECT * j'obtiens bien les résultats Oo'

    Possible que ce soit un problème d'encodage des accents ?

  17. #17
    Membre confirmé
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Points : 575
    Points
    575
    Par défaut
    oui
    nb : je n'ai pas relevé mais le next et le close de tchize sont bien entendu à conserver.

  18. #18
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Je dois donc engueuler l'utilisateur si il saisit un caractère accentué ou il existe une méthode plus propre pour gérer ça ?
    Je crois avoir vu la commande PRAGMA en cherchant sur le net mais j'ai un peu de mal à en comprendre le fonctionnement : http://www.theopensourcery.com/sqlitedocs/sqpragma.html

    En tout cas merci beaucoup de votre aide

  19. #19
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    vérifiez plutot que vos caractères accentués sont bien stockés dans la base de donnée.
    A tous les coup, vous avez mal écrit dans la DB, ce qui fait que lors du select vous n'avez rien. Si ca marche directement avec la console SGBD, c'est soit que vous envoyez mal votre requete avec java, soit que coté console SGDB, la même erreur de caractère est produite deux fois (une fois à l'insert, une fois au select), erreurs qui se compensent.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Operation not allowed after ResultSet closed
    Par Smix007 dans le forum JDBC
    Réponses: 3
    Dernier message: 10/03/2008, 17h28
  2. Réponses: 6
    Dernier message: 04/12/2007, 20h23
  3. [DataSource] ResultSet closed
    Par phoebe dans le forum Websphere
    Réponses: 3
    Dernier message: 08/12/2006, 16h15
  4. Réponses: 7
    Dernier message: 11/08/2006, 09h24
  5. Réponses: 2
    Dernier message: 19/04/2005, 15h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo