Как я могу избежать ResultSet является закрытым исключением в Java?
Как только мой код попадает в мой цикл while(rs.next())
, он выдает исключение ResultSet
. Что вызывает это исключение и как я могу его исправить?
EDIT: Я заметил в своем коде, что я вложен цикл while(rs.next())
с другим (rs2.next())
, оба набора результатов, исходящие из одного и того же БД, это проблема?
Ответы
Ответ 1
Похоже, что вы выполнили другой оператор в том же соединении, прежде чем пересечь результирующий набор из первого оператора. Если вы размещаете обработку двух наборов результатов из одной базы данных, вы делаете что-то неправильно. Комбинация этих наборов должна выполняться на стороне базы данных.
Ответ 2
Это может быть вызвано рядом причин, включая драйвер, который вы используете.
a) Некоторые драйверы не допускают вложенных операторов. В зависимости от того, поддерживает ли ваш драйвер JDBC 3.0, вы должны проверить третий параметр при создании объекта Statement. Например, у меня была такая же проблема с драйвером JayBird для Firebird, но код работал нормально с драйвером postgres. Затем я добавил третий параметр к вызову метода createStatement и установил его в ResultSet.HOLD_CURSORS_OVER_COMMIT, и код начал нормально работать и для Firebird.
static void testNestedRS() throws SQLException {
Connection con =null;
try {
// GET A CONNECTION
con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
String sql1 = "select * from reportes_clasificacion";
Statement st1 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs1 = null;
try {
// EXECUTE THE FIRST QRY
rs1 = st1.executeQuery(sql1);
while (rs1.next()) {
// THIS LINE WILL BE PRINTED JUST ONCE ON
// SOME DRIVERS UNLESS YOU CREATE THE STATEMENT
// WITH 3 PARAMETERS USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
System.out.println("ST1 Row #: " + rs1.getRow());
String sql2 = "select * from reportes";
Statement st2 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// EXECUTE THE SECOND QRY. THIS CLOSES THE FIRST
// ResultSet ON SOME DRIVERS WITHOUT USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
st2.executeQuery(sql2);
st2.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
rs1.close();
st1.close();
}
} catch (SQLException e) {
} finally {
con.close();
}
}
b) В вашем коде может быть ошибка. Помните, что вы не можете повторно использовать объект Statement, как только вы повторно выполняете запрос в одном и том же объекте оператора, все открытые результирующие группы, связанные с оператором, будут закрыты. Убедитесь, что вы не закрываете оператор.
Ответ 3
Кроме того, у каждого оператора может быть только один результирующий набор. Поэтому, если вы повторяете два набора результатов одновременно, убедитесь, что они выполняются в разных операторах. Открытие второго результирующего набора в одном выражении косвенно закрывает первое.
http://java.sun.com/javase/6/docs/api/java/sql/Statement.html
Ответ 4
Исключение указывает, что ваш результат закрыт. Вы должны изучить свой код и посмотреть все места, где вы вызываете вызов ResultSet.close()
. Также найдите Statement.close()
и Connection.close()
. Конечно, один из них вызывается до того, как вызывается rs.next()
.
Ответ 5
Возможно, вы закрыли либо Connection
, либо Statement
, которые сделали ResultSet
, что приведет к закрытию ResultSet
.
Ответ 6
Правильный вызов jdbc должен выглядеть примерно так:
try {
Connection conn;
Statement stmt;
ResultSet rs;
try {
conn = DriverManager.getConnection(myUrl,"","");
stmt = conn.createStatement();
rs = stmt.executeQuery(myQuery);
while ( rs.next() ) {
// process results
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
} finally {
// you should release your resources here
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
вы можете закрыть соединение (или оператор) только после получения результата из набора результатов. Самый безопасный способ - сделать это в блоке finally
. Однако close()
также мог бы задерживать SqlException
, следовательно, другой блок try-catch
.
Ответ 7
Проверьте, был ли вы объявлен метод, в котором этот код выполняется как static
. Если это static
, может быть какой-то другой поток, сбросив ResultSet
.
Ответ 8
У меня такая же ошибка, все было правильно, только я использовал тот же объект интерфейса оператора для выполнения и обновления базы данных.
После разделения, то есть с использованием разных объектов интерфейса оператора для обновления и выполнения запроса, я решил эту ошибку. то есть избавиться от этого, не используйте один и тот же объект-оператор для обновления и выполнения запроса.
Ответ 9
перед запуском rs.next убедитесь, что вы закрыли все свои статистические данные и наборы результатов. В конечном итоге это гарантирует
public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
LogUtil.logRequestMethod();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
ps.setInt( 1, idStatusPrevious );
ps.setInt( 2, idStatus );
rs = ps.executeQuery();
Long count = 0L;
if ( rs != null ) {
while ( rs.next() ) {
count = rs.getLong( 1 );
break;
}
}
LogUtil.logSuccessMethod();
return count > 0L;
} catch ( Exception e ) {
String errorMsg = String
.format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
LogUtil.logError( errorMsg, e );
throw new FatalException( errorMsg );
} finally {
rs.close();
ps.close();
}
Ответ 10
ResultSetClosedException
может быть вызвано по двум причинам.
1.) Вы открыли другое соединение с базой данных, не закрывая все остальные соединения.
2.) Ваш ResultSet может не возвращать значения. Поэтому при попытке получить доступ к данным из ResultSet java сгенерирует ResultSetClosedException
.