4 votes

<table> <tr> <td>jdbc ResultSet fermé</td> </tr> </table>

J'ai la source suivante.

Dans insertMessage(..), il appelle selectMessage pour vérifier si un enregistrement en double existe ou non.

Mais cette erreur se produit. Dans mon cerveau, ça fonctionne bien parce que la source de données me donne une nouvelle connexion...peut-être

java.sql.SQLException: ResultSet fermé
    at org.sqlite.RS.checkOpen(RS.java:63)
    at org.sqlite.RS.findColumn(RS.java:108)
    at org.sqlite.RS.getString(RS.java:317)
    at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:263)
    at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:263)
    at org.springframework.context.support.CachedMessageSourceDao.selectMessage(CachedMessageSourceDao.java:68)
    at org.springframework.context.support.CachedMessageSourceDao.insertMessage(CachedMessageSourceDao.java:94)
    at MessageSourceDemo.main(MessageSourceDemo.java:11)

public String selectMessage(String code, String language) {
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    String value = null;

    String sql = "SELECT code, value, language FROM " + TABLE + " where code=? and language=? and flag = '" + FLAG_OK + "'";

    try {
        conn = dataSource.getConnection();
        conn.setAutoCommit(true);
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, code);
        pstmt.setString(2, language);
        rs = pstmt.executeQuery();
        rs.next();

        String _code = rs.getString("code");
        String _value = rs.getString("value");
        String _language = rs.getString("language");
        Locale _locale = new Locale(_language);
        value = _value;

    } catch(SQLException ex) {

        ex.printStackTrace();

    } finally {

        try {
            if(rs != null);
            if(pstmt != null) pstmt.close();
            if(conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
    return value;
}

public synchronized void insertMessage(String code, String value, String language) throws SQLException {
    //Vérification de message en double
    **if(selectMessage(code, language) != null) throw new SQLException("Un message en double existe pour le code : " + code + " et " + "le language : " + language);**

    String sql = "INSERT INTO " + TABLE + " (code, value, language, flag) values (?, ?, ?, '" + FLAG_OK + "')";

    Connection conn = null;
    PreparedStatement pstmt = null;

    try {
        conn = dataSource.getConnection();
        conn.setAutoCommit(true);
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, code);
        pstmt.setString(2, value);
        pstmt.setString(3, language);
        pstmt.execute();

    } catch(SQLException ex) {

        ex.printStackTrace();

    } finally {

        try {

            if(pstmt != null) pstmt.close();
            if(conn != null) conn.close();

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    notifyMessageChange(); //Application en temps réel à MessageSource
}

7voto

dystroy Points 145126

Votre resultset n'avait probablement aucun enregistrement, c'est la raison pour laquelle next() l'a fermé.

[next()](http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/ResultSet.html#next()) renvoie un booléen, vérifiez-le.

2voto

ejb_guy Points 1094

Vérifiez la valeur de rs.next(); Elle doit renvoyer false. Vous devez faire ceci.

   if(rs.next()){
       //obtenir les données

   }

2voto

JHS Points 4317

Vous devriez vérifier ce que rs.next renvoie. Si c'est false, cela signifie que rien n'a été récupéré.

Maintenant, si vous utilisez if(rs.next), alors vous ne considérez que la 1ère ligne que le ResultSet a renvoyée. Si la requête renvoie plus d'une ligne et que vous voulez toutes les considérer, utilisez while(rs.next).

Encore une fois, même si vous ajoutez while(rs.next) avant votre code, les valeurs de _code, _value, _language _locale seraient celles de la dernière ligne renvoyée dans le ResultSet. Vous devez donc modifier votre code en conséquence.

1voto

Sajmon Points 16675

Vous ne pouvez pas seulement ajouter rs.next() car ResultSet peut être vide, donc vous devez ajouter des conditions et des tests si le résultat de next() est une ligne valide, sinon il renvoie false.

conn = dataSource.getConnection();
        conn.setAutoCommit(true);
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, code);
        pstmt.setString(2, language);
        rs = pstmt.executeQuery();
        if (rs.next())

        String _code = rs.getString("code");
        String _value = rs.getString("value");
        String _language = rs.getString("language");
        Locale _locale = new Locale(_language);
        value = _value;
    }

1voto

Addicted Points 1646

À la place de cela -

rs.next();
String _code = rs.getString("code");
String _value = rs.getString("value");
String _language = rs.getString("language");

Utilisez ceci -

while(rs.next()) //ou utilisez if (s'il n'y a qu'une seule ligne dans le jeu de résultats)
{
    String _code = rs.getString("code");
    String _value = rs.getString("value");
    String _language = rs.getString("language"); 
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X