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

Servlets/JSP Java Discussion :

SQLexception: Operation not allowed after ResultSet closed


Sujet :

Servlets/JSP Java

  1. #1
    Membre régulier Avatar de fripette
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 241
    Points : 71
    Points
    71
    Par défaut SQLexception: Operation not allowed after ResultSet closed
    Bonjour !
    J'ai un problème avec mes fondamentaux décidément.
    Je bloque encore sur un truc tout bête.

    Je crée au début de mon script des lignes dans ma table et si elles ne sont pas remplies apres mon traitement alors je vais les effacer.
    Voici le coté servlet:
    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
    void doActualisationFormDonnee(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    		Connexion updatePrlvmt= new Connexion();
    
    		if (listIdPrelevement.isEmpty()){
    			getServletContext().getRequestDispatcher((String) params.get("urlFormulaire")).forward(request,
    					response);       
    			return;
    		}
    
    		else{
    //serveur,login,pwd,database
    				updatePrlvmt.loadDriverAndConnect("127.0.0.1","3306","root","root","");
    
    				//
    
    				// ETAPE 1 :recuperation de la signification de chacun des indices
    				for (int j=0; j<listIndice.length; j++) {
    					String query="insert into CorrespIndiceEBM values ('"+NEtude +"','"+listIndice[j] +"','null','null','null','null','null','null'," +
    					"'null','null','null','null','null','null')";
    					updatePrlvmt.execute(query);
    
    					for (int k=1; k<=listIndice.length; k++) {
    			try{	[TRAITEMENT: INSERTION DES VALEURS DE L'UTILISATEUR DANS LES LIGNES ADEQUATES]
    	// si apres la création de la ligne concernant la lettre, il n'y a pas eu d'information rentré (donc status='null') 
    				// alors on supprime la ligne
    				for (int m=0; m<listIndice.length; m++) {	
    					String queryCheck="SELECT Corresp1,Corresp2,Corresp3,Corresp4" +
    							" FROM CorrespIndiceEBM where Netude='"+NEtude+"' AND lettre='"+listIndice[m]+"'";
    					
    					ResultSet rsCheck=updatePrlvmt.ConnectAndQuestion(queryCheck);
    					
    					while (rsCheck.next()){
    						String Corresp1= rsCheck.getString("Corresp1");
    						String Corresp2= rsCheck.getString("Corresp2");
    						String Corresp3= rsCheck.getString("Corresp3");
    						String Corresp4= rsCheck.getString("Corresp4");
    											
    						if (Corresp1.equals("null") && Corresp2.equals("null") && Corresp3.equals("null") && Corresp4.equals("null")){
    							updatePrlvmt.execute("delete FROM CorrespIndiceEBM " +
    									" where Netude='"+NEtude+"' AND lettre='"+listIndice[m]+"'");
    						}
    						
    					}
    					
    				}
    Voilà le message d'erreur que j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Connected to :	jdbc:mysql://127.0.0.1:3306/BIOTECH
     
    *** SQLException caught in main()
    java.sql.SQLException: Operation not allowed after ResultSet closed
    	at com.mysql.jdbc.ResultSet.checkClosed(ResultSet.java:652)
    	at com.mysql.jdbc.ResultSet.next(ResultSet.java:5942)
    	at com.mysql.jdbc.UpdatableResultSet.next(UpdatableResultSet.java:975)
    	at germande.EBM.ServletDonneeResultEBM.doActualisationFormDonnee(ServletDonneeResultEBM.java:249)
    Donc je ne comprend absolument pas ce qu'il se passe !! J'y comprend rien !
    Je n'ai pas fermé la connection.
    Par exemple quand seule les correspondances de la lettre "a" sont remplies : j'ai bien la ligne concernant la lettre "a "qui est gardé dans la table mais aussi "c" et "d" mais pas "b" !!
    Une idée s'il vous plait ??
    Merci d'avance !

  2. #2
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    Citation Envoyé par fripette Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ResultSet rsCheck=updatePrlvmt.ConnectAndQuestion(queryCheck);
    Je suppose que ta méthode s'occupe d'exécuter la requête et de renvoyer le ResultSet. Le problème, c'est qu'elle doit également fermer le Statement utilisé pour la requête, et, foi de javadoc, si le Statement est fermé, le ResultSet l'est également. Du coup, impossible d'en extraire le contenu.

    Donc soit tu changes la signature de ta méthode pour qu'elle te renvoi une liste d'objets complètement décorelée des couches JDBC, soit tu ne ferme pas le Statement, mais tu l'ajoute à une liste de ressources à libérer et tu ajoute une méthode close() générale à ton objet Connexion.
    Pour éviter de bricoler un utilitaire, utilise des libs qui facilitent ce genre d'opérations, comme DbUtils

  3. #3
    Membre régulier Avatar de fripette
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 241
    Points : 71
    Points
    71
    Par défaut
    Il semble que ma méthode ne ferme pas le Rs:
    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
     
    public ResultSet ConnectAndQuestion(String query) throws Exception
    		{
    			try {
    				String user="root";
    				String pwd="root";
     
    				Class.forName("com.mysql.jdbc.Driver").newInstance();
    				String url=("jdbc:mysql://127.0.0.1:3306/BIOTECH");
     
    				conn = DriverManager.getConnection(url, user,pwd);
     
    				statement = conn.createStatement(
    						ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE );
    				resultSet=statement.executeQuery(query);
    				 // Print stdout warning messages if necessary
    		         checkForSQLWarnings(conn.getWarnings());
     
    			    // Print stdout info messages
    		     }
    			catch(SQLException e) {
    			    System.err.println("\n*** SQLException caught in LoadDriver()");
    			    printSQLErrors(e);
    		         throw(SQLException) e;
    		     }
    		     catch(Exception e) {
    			    // This exception is caught if JDBC driver used cannot be loaded
    			    System.err.println("\n*** Exception caught in LoadDriver()"+e);
    		         throw(Exception) e;
    		     }
    			return resultSet;
    		}

  4. #4
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    C'est encore pire que ce que je pensais ....
    Qui ferme les Statement, ResultSet et Connection alors Le GC , cf javadoc
    Petit conseil, jette vite ta classe Connexion.

  5. #5
    Membre régulier Avatar de fripette
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 241
    Points : 71
    Points
    71
    Par défaut
    J'ai aussi une méthode dans ma classe connexion qui s'appelle close():
    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
     
     /**
    	  *	Close the connection to the data base source
    	  */
    	 public void close() throws Exception
    	 {
    		try {
    		    resultSet.close();
    		    statement.close();
    		    conn.close();
     
     
    		    System.out.println("Deconnexion...");
     
    	     }
    	     catch(Exception e) {
    		    System.err.println("\n*** Exception caught in close()");
    	        throw e; 
     
    	     }
    	 }
    qui va donc être appelé apres tous mes traitements en fin de script ... rassurant ?

    En tout cas, je ne vois pas pourquoi il y a ce message d'erreur

  6. #6
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    Citation Envoyé par fripette Voir le message
    J'ai aussi une méthode dans ma classe connexion qui s'appelle close(): qui va donc être appelé apres tous mes traitements en fin de script ... rassurant ?
    Oui !, j'ai fait mon , j'ai pas lu assez attentivement.
    Toutefois, si ta méthode close() s'occupe uniquement d'un seul statement, ta classe n'aurait-elle pas un pb lors de la séquence suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ResultSet rsCheck=updatePrlvmt.ConnectAndQuestion(requete1);
    while (rsCheck.next()){
       [...]
       updatePrlvmt.execute(requete2);
    }
    On créer le statement pour la requete 1, puis on l'écrase pour créer celui de la requete 2 non ? CQFD ?

  7. #7
    Membre régulier Avatar de fripette
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 241
    Points : 71
    Points
    71
    Par défaut
    On utilise effectivement le même statement mais apres je ne sais pas s'il est écrasé ou pas.
    Voici le code de la méthode execute (non pas celle du paquage java.sql):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public void execute(String query){
    		 if (conn == null || statement == null) {
    			 System.err.println("There is no database to execute the query.");
    			 return;
    		 }
    		 try {
    			 statement.execute(query);
    			 //fireTableChanged(null); // Tell the listeners a new table has arrived.
    		 }
    		 catch (SQLException ex) {
    			 System.err.println("erreur execQuery: "+ex);
    		 }
    	 }
    En tout cas, je dois t'avouer que tu m'as fait peur ! Ca avance pas mon chmilblick

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Le problème vient du fait que tu utilises le même Statement, le premier est irrémédiablement perdu à l'exécution de ta sous-requête.

    L'usage d'un Statement pour des insertions ou des modifications en base de données n'est vraiment pas une solution, il faudrait vraiment passer aux PreparedStatement.

    La logique généralement appliquée est la suivante :
    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
     
    public void maMethode(...)
    {
       Connection connection = null;
       try
       {
          connection = MaClasseUtilitaire.getConnection();
     
          PreparedStatement pstmt = connection.prepareStatement("insert into maTable(col1, col2) values(?, ?)");
     
          Statement stmt = connection.createStatement();
          ResultSet rs = stmt.executeQuery("select c1, c2 from uneAutreTable");
          while ( rs.next() )
          {
             pstmt.setInt(1, rs.getInt("c1"));   <- on suppose que c1 est un entier
             pstmt.setString(2, rs.getString("c2"));  <- on suppose que c2 est un String
             pstmt.executeUpdate();
          }
       }
       catch (Exception e)
       {
          ...
       }
       finally
       {
          if ( connection != null ) connection.close();
       }
    }

  9. #9
    Membre régulier Avatar de fripette
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 241
    Points : 71
    Points
    71
    Par défaut
    Effectivement, OButterlin!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Le problème vient du fait que tu utilises le même Statement, le premier est irrémédiablement perdu à l'exécution de ta sous-requête.
    Pour le moment je crée un nouvel objet connexion pour chaque élèment traité. (de la listIndice).

    Mais je vais appliquer ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    L'usage d'un Statement pour des insertions ou des modifications en base de données n'est vraiment pas une solution, il faudrait vraiment passer aux PreparedStatement.
    Merci merci !!

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 26/03/2013, 10h55
  2. Erreur "Operation not allowed after ResultSet closed"
    Par boubounagh dans le forum JDBC
    Réponses: 18
    Dernier message: 28/01/2012, 15h42
  3. Operation not allowed after ResultSet closed
    Par menakikou dans le forum Débuter
    Réponses: 1
    Dernier message: 22/09/2009, 16h38
  4. Operation not allowed after ResultSet closed
    Par Smix007 dans le forum JDBC
    Réponses: 3
    Dernier message: 10/03/2008, 17h28
  5. Réponses: 7
    Dernier message: 11/08/2006, 09h24

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