Parcourir une Jtable, ResultSet closed [Résolu]

zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 29 juil. 2016 à 21:56 - Dernière réponse : zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention
- 1 août 2016 à 20:49
Bonjour,
je veux parcourir une Jtable et ensuite je dois au fur et mesure de la lecture d'une ligne, diminuer la quantité du stock de la table produit( bien-sur en recherchant à chaque fois le code du produit).
Voici la structure de ma table produit: CodePd, NomPd,QtePd, PxAchat, PxVente, DateVente. mais une erreur me parvient toujours et je suis dans l'embrouille:
""Operation not allowed after ResultSet closed.""
et voici mon code :
private void enrFactActionPerformed(java.awt.event.ActionEvent evt) {                                       
        int q1, id_Pd;
        try{
            for (int i=0; i<model2.getRowCount();i++){
                txtCodePd.setText(model2.getValueAt(i, 0).toString());
                txtQteV.setText(model2.getValueAt(i, 1).toString());
                q1=Integer.parseInt(txtQteV.getText());
            try{
                st=conn.obtenirConnexion().createStatement();
                Rs=st.executeQuery("SELECT * FROM produits where CodePd='"+txtCodePd.getText()+"'");
            }catch(SQLException e){System.err.println(e);}
                Rs.next();
                int oldQte=Rs.getInt(3);
//q1 est la quantité à diminuer du stock
                oldQte=oldQte-q1;
                String oq=Integer.toString(oldQte);
                txtQteVTable.setText(oq);
                st.executeUpdate("UPDATE produits SET QtePd ='"+txtQteVTable.getText()+"' WHERE CodePd= "+txtCodePd.getText());
            }           
        }catch(SQLException e){System.err.print(e.getMessage());}
}        

Merci de me répondre...@mar
Afficher la suite 

11 réponses

Répondre au sujet
KX 15225 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 février 2018 Dernière intervention - 30 juil. 2016 à 13:05
0
Utile
Bonjour,

Visiblement il y a des incompréhensions sur les exceptions...

System.err.println(e);
n'est pas suffisant pour obtenir des informations sur l'erreur, il vaudrait mieux utiliser
e.printStackTrace();
ou des Logger.

De plus ce code n'a pas de sens :
try {
    st=conn.obtenirConnexion().createStatement();
    Rs=st.executeQuery("SELECT * FROM ...");
} catch(SQLException e) {
    System.err.println(e);
}
Rs.next();

Si tu obtiens une erreur lors de la connexion, ou l'exécution de la requête alors ça ne sert à rien de faire un Rs.next(), tu ne pourras jamais avoir de résultats à ta requête puisqu'elle a échouée dans le try/catch

De plus, st et Rs devraient être des variables locales, ça n'a pas de sens de les déclarer au niveau de l'objet, ça va entraîner des effets de bords monstrueux, et c'est d'ailleurs le cas dans ton erreur :

"Operation not allowed after ResultSet closed" car tu as du utiliser Rs dans une autre méthode, où tu l'as fermé, sauf que tu le réutilises dans cette méthode où la connexion ou la requête ont du planter mais tu essayes quand même de faire un Rs.next() sur l'ancienne valeur de Rs, celle de l'autre méthodes... un beau bazar.

Remarque : je t'incites à utiliser un try-with-resources pour faire des ouvertures et fermetures propres de tes connexions, ainsi que des PreparedStatement pour éviter des injections SQL

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Et pour simplifier ton code, je t'invites à clairement séparer ton code Swing de ton code de base de données, en appelant des méthodes séparées.

Exemple :

public int getQtePd(String codePd) throws SQLException {
    try (Connection conn = obtenirConnexion()) {
        String sql = "SELECT QtePd FROM produits where CodePd = ?";
        try (PreparedStatement st = conn.prepareStatement(sql)) {
            st.setString(1, codePd);
            try (ResultSet rs = st.executeQuery()) {
                if (!rs.next()) {
                    throw new IllegalStateException("getQtePd has no row for " + codePd);
                }
                int qte = rs.getInt("QtePd");
                if (rs.next()) {
                    throw new IllegalStateException("getQtePd has more than 1 row for " + codePd);
                }
                return qte;
            }
        }
    }
}

public void setQtePd(String codePd, int qtePd) throws SQLException {
    try (Connection conn = obtenirConnexion()) {
        String sql = "UPDATE produits SET QtePd = ? WHERE CodePd = ?";
        try (PreparedStatement st = conn.prepareStatement(sql)) {
            st.setInt(1, qtePd);
            st.setString(2, codePd);
            int counts = st.executeUpdate();
            if (counts != 1) {
                throw new IllegalStateException("setQtePd has changed " + counts + " rows for " + codePd + " (1 was expected)");
            }
        }
    }
}

private void enrFactActionPerformed(ActionEvent evt) {
    for (int i = 0; i < model2.getRowCount(); i++) {
        try {
            String codePd = model2.getValueAt(i, 0).toString();
            txtCodePd.setText(codePd);

            String qteV = model2.getValueAt(i, 1).toString();
            txtQteV.setText(qteV);

            int oldQte = getQtePd(codePd);
            int newQte = oldQte - Integer.parseInt(qteV);
            setQtePd(codePd, newQte);

            txtQteVTable.setText(Integer.toString(newQte));
        } catch (SQLException | RuntimeException e) {
            Logger.getLogger(getClass().toString()).log(Level.SEVERE, "Can't enrFactActionPerformed: " + i, e);
        }
    }
}
Commenter la réponse de KX
zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 31 juil. 2016 à 10:05
0
Utile
Merci beaucoup KX..
Commenter la réponse de zerargui
zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 31 juil. 2016 à 10:24
0
Utile
8
Bonjour KX,
J'ai une erreur comme indiquée sur l'image :


cann't find symbol
Symbol : Method obtenirConnection()



Local variable hides a field.
zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention > KX 15225 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 février 2018 Dernière intervention - 1 août 2016 à 10:19
Bonjour KX,
le projet est bien compilé mais une erreur à l’exécution :

GRAVE: Can't enrFactActionPerformed: 3
java.lang.IllegalStateException: getQtePd has no row for
at MyFrames.FrameVentes.getQtePd(FrameVentes.java:1518)
at MyFrames.FrameVentes.enrFactActionPerformed(FrameVentes.java:1499)
at MyFrames.FrameVentes.access$2800(FrameVentes.java:24)
at MyFrames.FrameVentes$29.actionPerformed(FrameVentes.java:720)


à la ligne du code suivant dans la méthode getQtePd() :

throw new IllegalStateException("getQtePd has no row for " + codePd);
KX 15225 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 février 2018 Dernière intervention > zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 1 août 2016 à 17:49
GRAVE: Can't enrFactActionPerformed: 3 
java.lang.IllegalStateException: getQtePd has no row for 

Cela signifie que dans ta table model2, à la ligne 3 (la 4è ligne vu qu'on commence à 0), tu as codePd="" et que cette valeur n'existe pas en base de données, il ne peut donc pas la traiter correctement.
Il va falloir rajouter un peu de code pour gérer les cas particuliers mais s'il ne plante qu'à la 4è ligne ça veut dire qu'il a réussi les 3 premières apparemment donc on doit pas être trop loin du résultat...
zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 1 août 2016 à 18:36
re-bonjour KX,
c bien compris je vais essayer de corriger cela. Merci
zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 1 août 2016 à 20:15
ce que j'ai modifié dans le code et ça marche très bien
for (int i = 0; i < model2.getRowCount()-2; i++) {


dans mon model2 je ne parcours plu les 2 dernières lignes où dans la 1ere j'affiche une ligne blanche et dans la dernière le total de la facture donc je n'arrive jamais à une exception.
Tout un grand merci à toi KX.
zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention > zerargui 64 Messages postés vendredi 24 octobre 2008Date d'inscription 14 novembre 2017 Dernière intervention - 1 août 2016 à 20:49
ben je tenais à vous informer de ma façon à faire.
1001 merci à toi KX.
Commenter la réponse de zerargui

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.