Domanda

When running this code, I get a ResultSet closed error. The called methods and data are as follows:

Log output:

[2014-05-05 22:34:09.169 Debug] select count(*) as total from companies
[2014-05-05 22:34:09.170 Debug] ResultSet closed

Methods:

public static Boolean recordsExist(String string, Connection c) {
    try {
        String[] query = string.split("\\*");
        String sql = "select count(*) as total" + query[1];
        ResultSet resultset = queryDB(sql, c);
        resultset.next();
        int count = resultset.getInt(1);
        Log.debug(Integer.toString(count));
        resultset.close();
        if (count > 0) {
            Log.debug("recordsExist returning true");
            return true;
        } else {
            Log.debug("recordsExist returning false");
            return false;
        }

    } catch (Exception e) {
        Log.debug(e.getMessage());
        return false;
    }
}

public static ResultSet queryDB(String sql, Connection c) throws SQLException {
    Log.debug(sql);
    Statement s = c.createStatement();
    ResultSet resultset = s.executeQuery(sql);
    s.close();
    return resultset;
}

Sql string specified:

select * from companies
È stato utile?

Soluzione 2

Don't close the Statement. Scenario is like this first close resultset then statement. Write you code like this:

    public static Boolean recordsExist(String string, Connection c) {
    try {
        String[] query = string.split("\\*");
        String sql = "select count(*) as total" + query[1];
        Statement s = c.createStatement();
        ResultSet resultset = queryDB(sql, c, s);
        resultset.next();
        int count = resultset.getInt(1);
        Log.debug(Integer.toString(count));
        resultset.close();
        s.close();
        if (count > 0) {
            Log.debug("recordsExist returning true");
            return true;
        } else {
            Log.debug("recordsExist returning false");
            return false;
        }

    } catch (Exception e) {
        Log.debug(e.getMessage());
        return false;
    }
}

public static ResultSet queryDB(String sql, Connection c, Statement s ) throws SQLException {
    Log.debug(sql);
    ResultSet resultset = s.executeQuery(sql);
    return resultset;
}

Altri suggerimenti

From the Java API:

Note:When a Statement object is closed, its current ResultSet object, if one exists, is also closed.

You will need to process the data in the ResultSet before closing the Statement. Something along these lines should work:

public static Boolean recordsExist(String string, Connection c) {
    try {
        String[] query = string.split("\\*");
        String sql = "select count(*) as total" + query[1];
        return queryDB(sql, c);


    } catch (Exception e) {
        Log.debug(e.getMessage());
        return false;
    }
}

public static boolean queryDB(String sql, Connection c) throws SQLException {
    Log.debug(sql);
    Statement s = c.createStatement();
    ResultSet resultset = s.executeQuery(sql);
    boolean result = processResult(resultset);
    s.close();
    return result;
}

public static boolean processResult(ResultSet resultset) {
    resultset.next();
    int count = resultset.getInt(1);
    Log.debug(Integer.toString(count));
    resultset.close(); 
    if (count > 0) {
        Log.debug("recordsExist returning true");
        return true;
    } else {
        Log.debug("recordsExist returning false");
        return false;
    }

}

I would also consider adding more error handling to ensure that you do not leak resources. For instance if an Exception occurs when processing the result then your statement will not be properly closed.

Always check for next result set first as shown below

 if(resultset.next()){
     int count = resultset.getInt(1);
 }

I have already posted a nice ConnectionUtil class to manage all the connections in a single class for whole application.


Close the Statement, ResultSet and Connection in finally clause in the end to make sure that all are closed in any case as shown in below code.

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    ...
} finally {
    if (rs != null) {
        rs.close();
    }
    if (stmt != null) {
        stmt.close();
    }
    if (conn != null) {
        conn.close();
    }
} 

Note: Don't use Log.debug(e.getMessage()); for ERROR message otherwise you will be lost in logs to find out the errors only.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top