[Résolu][Java]Déclarer un ResultSet updatable

Hello les geeks

J’ai un ResultSet initialisé de la façon suivante:

ResultSet rs = null
...
rs = Bean.Machin();

le problème c’est que le resultset que je récupère est un read-only alors qu’il est bien créé comme un updatable!
la preuve dans ma méthode Machin():

Statement stm = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            String query  = "SELECT * FROM ProduitsEnvoyes WHERE ID_SuperMarche = " + idSM;
            System.out.println(query);
            ResultSet rs = stm.executeQuery(query);

Comment faire pour que quand je déclare rs, il soit considéré comme updatable? (fatalement je peux pas refaire le brol de créer le statement à chaque fois…)

précise les champs de ta table en oubliant surtout pas l’id si tu veux qu’il soit updatable

edit: au lieu d’un bête * donc

Je t’invite a éditer ton post afin d’y ajouter toutes les informations qui te semblent pertinentes. Quelle base de donnée, quel driver JDBC, comment tu te rends compte que ton resultset est « pas updatable », ton user a-t-il bien les droits écriture sur la table ? est-ce que t’as essayé en récupérant une seule colonne de ta table? Enfin tout ça, quoi. Un minimum d’effort.

La comme ça, ton poste ressemble vaguement a un « j’ai un problème quand je fais quelque chose qui devrait marcher. Quelqu’un peut m’aider ? »
La bonne réponse étant en général « non », a mois que tu fournisses un peu plus d’infos.

La réponse peut sembler un peu brutale, mais j’ai jamais compris les devs qui soumettent des bugs/demandent de l’aide sans fournir d’infos détaillée.
Quand un client vous soumet un bug/demande un supplément d’explication, la première chose que vous lui demandez, c’est de savoir ce que la personne a fait et pourquoi elle pense qu’il y a un problème, non ? Si vous envoyez ces infos des la première question, en général, ca économise du temps.

Désolé pour le ton du post, j’ai eu affaire à ce genre de bugs un peu trop souvent a mon goût au taff :slight_smile:

C’est parti pour le bug report

Donc, j’ai un client faisant tourner (entre autres) un thread qui “écoute” une BD Oracle (11g) via un JavaBeans (driver jdbc Oracle - ojdbc6.jar récupéré sur le site d’Oracle), et qui, dans l’idéal, va récupérer un ResultSet. Elle passe ce ResultSet à une fonction qui, pour chaque row, va créer un objet Produit maison contenant toutes ses infos. Cet object Produit est envoyé à un serveur qui va, via un autre JavaBeans, tenter d’insérer le tuple dans une BD MySQL. Si l’insertion se fait bien (ce qui est le cas), il faut supprimer le tuple correspondant dans la BD Oracle (d’où mon besoin d’appeler la méthode deleteRow() du ResultSet) => C’est à cet endroit que j’ai une SQLException me disant que le ResultSet est read-only.

Le code du thread:

ResultSet rs;
while(true)
{
    rs = bc.Detect();
    if(rs != null)
    {
        JOptionPane.showMessageDialog(men, "Produits arrivé de la Centrale",
                "Arrivage détecté", JOptionPane.INFORMATION_MESSAGE);
        int res = Common.Prohap.askReceive(rs, men.conn);
        if(res == -1)
            JOptionPane.showMessageDialog(men, "L'arrivage n'a pu être enregistré",
                    "Erreur", JOptionPane.ERROR_MESSAGE);
        else
            JOptionPane.showMessageDialog(men, res + " produits enregistrés",
                    "Info", JOptionPane.INFORMATION_MESSAGE);
    }
    else
        JOptionPane.showMessageDialog(men, "Pas de nouvel arrivage", "Info",
                JOptionPane.INFORMATION_MESSAGE);
    try
    {
        Thread.sleep(30 * 1000);
    } catch(InterruptedException e) {
        System.err.println("Erreur de délai entre les arrivages !");
    }
}

Le code de la fonction Detect:

Statement stm = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); //conn = connection à la BD Oracle
String query  = "SELECT * FROM ProduitsEnvoyes WHERE ID_SuperMarche = " + idSM; //idSM = numéro du supermarché concerné
System.out.println(query);
ResultSet rs = stm.executeQuery(query);
boolean res = rs.next();
if(res)
    return rs;

rs.close();
stm.close();
return null;

la méthode qui fait le lien entre le client et le serveur:

try
{
    int cpt = 0;
    ObjectOutputStream oos = new ObjectOutputStream(conn.dos);
    do
    {
        EnvoiProduit produit = new EnvoiProduit();
        produit.idArticle = rs.getString("ID_Article");
        produit.idConditionnement = rs.getInt("ID_Conditionnement");
        produit.idEmballage = rs.getInt("ID_Emballage");
        produit.DatePeremption = rs.getString("DatePeremption");
        produit.prix = rs.getFloat("PrixVente");
        produit.quantite = rs.getInt("Quantite");
        conn.writeInt(1);
        oos.writeObject(produit);
        if(conn.readInt() == 0)
        {
            System.out.println("test pre delete");
            rs.deleteRow(); //ça plante!
            System.out.println("test post delete " + cpt);
            cpt++;
        }
    } while(rs.next());
    rs.close();
    conn.writeInt(0);
    return cpt;

} catch(SQLException e) {
    e.printStackTrace();
    System.err.println("Erreur SQL durant le transfert des produits reçus !");
    return -1;

} catch(IOException e) {
    System.err.println("Erreur d'envoi des infos produits reçus !");
    return -1;
}

STACKTRACE:

java.sql.SQLException: Opération non valide sur un ensemble de résultats de type read-only: deleteRow
        at oracle.jdbc.driver.BaseResultSet.deleteRow(BaseResultSet.java:999)
        at Common.Prohap.askReceive(Prohap.java:354)
        at Common.ThArrivages.run(ThArrivages.java:28)

Sinon:

  • oui j’ai les droits nécessaires sur la table
  • Ivru tu crois vraiment qu’un “Select toutes mes colonnes” au lieu d’un “Select *” va changer le comportement du resultset alors que je demande explicitement un CONCUR_UPDATABLE ?

Premier lien google…

Et parce que je suis un mec super sympa voici le passage intéressant: “For some drivers, `SELECT * FROM my_table’ will return a read-only result set, so make sure that you specify the column names.”

Ben merde alors o_O, ça vaut bien la peine de spécifier que tu veux un ResultSet updatable.

Ivru wins cake!