Allright been trying to figure this out the last 2 days.
Statement statement = con.createStatement();
String query = "SELECT * FROM sell";
ResultSet rs = query(query);
while (rs.next()){//<--- I get there operation error here
This is the query method.
public static ResultSet query(String s) throws SQLException {
try {
if (s.toLowerCase().startsWith("select")) {
if(stm == null) {
createConnection();
}
ResultSet rs = stm.executeQuery(s);
return rs;
} else {
if(stm == null) {
createConnection();
}
stm.executeUpdate(s);
}
return null;
} catch (Exception e) {
e.printStackTrace();
con = null;
stm = null;
}
return null;
}
How can I fix this error?
wattostudios
8,65613 gold badges43 silver badges57 bronze badges
asked Jun 7, 2012 at 14:01
2
It’s hard to be sure just from the code you’ve posted, but I suspect that the ResultSet
is inadvertently getting closed (or stm
is getting reused) inside the body of the while
loop. This would trigger the exception at the start of the following iteration.
Additionally, you need to make sure there are no other threads in your application that could potentially be using the same DB connection or stm
object.
answered Jun 7, 2012 at 14:06
NPENPE
484k108 gold badges948 silver badges1010 bronze badges
1
IMHO, you should do everything you need with your ResultSet before you close your connection.
answered Jun 7, 2012 at 14:22
iozeeiozee
1,3391 gold badge12 silver badges24 bronze badges
there are few things you need to fix. Opening a connection, running a query to get the rs, closing it, and closing the connection all should be done in the same function scope as far as possible. from your code, you seem to use the «con» variable as a global variable, which could potentially cause a problem. you are not closing the stm object. or the rs object. this code does not run for too long, even if it has no errors. Your code should be like this:
if (stringUtils.isBlank(sql)){
throw new IllegalArgumentsException ("SQL statement is required");
}
Connection con = null;
PreparedStatement ps =null;
Resultset rs = null;
try{
con = getConnection();
ps = con.preparestatement(sql);
rs = ps.executeQuery();
processResults(rs);
close(rs);
close(ps);
close(con);
}catch (Execption e){
log.Exception ("Error in: {}", sql, e);
throw new RuntimeException (e);
}finally{
close(rs);
close(ps);
close(con);
}
answered Jun 7, 2012 at 14:33
srini.venigallasrini.venigalla
5,1271 gold badge18 silver badges29 bronze badges
use another Statement object in inner loop
Like
Statement st,st1;
st=con.createStatement();
st1=con.createStatement();
//in Inner loop
while(<<your code>>)
{
st1.executeQuery(<<your query>>);
}
answered Jun 30, 2013 at 1:33
I know this is a few years late, but I’ve found that synchronizing the db methods usually get rid of this problem.
answered Nov 22, 2013 at 8:39
ZeeZee
1,58212 silver badges26 bronze badges
0
- Java Error
java.sql.SQLException: Operation not allowed after ResultSet closed
- Fix Java Error
java.sql.SQLException: Operation not allowed after ResultSet closed
This tutorial demonstrates the java.sql.SQLException: Operation not allowed after ResultSet closed
error in Java.
Java Error java.sql.SQLException: Operation not allowed after ResultSet closed
The error Operation Not Allowed After Resultset Closed
is an SQL exception when we try to access a closed result set. As the Java Doc mentions, whenever a statement object is closed, If its Resultset
object exists, it will also be closed.
The problem with the error is that the Resultset
instance will also save the underlying statement. So when the underlying statement is closed, the Resultset
will also be closed, which throws the error.
Here’s a snippet of code that will throw the same error.
Code:
ResultSet Result_Set; // class variable
Statement Demo_Statement = null;
try{
Demo_Statement = DB_Connection.createStatement();
Result_Set = Demo_Statement.getGeneratedKeys();
}
catch (Exception e){
throw e;
}
finally{
try{
if (Demo_Statement != null)
Demo_Statement.close();
} catch (SQLException e){
throw e;
}
}
System.out.println(Result_Set.next());
The code above with a database connection will throw the following error.
java.sql.SQLException: Operation not allowed after ResultSet closed
Fix Java Error java.sql.SQLException: Operation not allowed after ResultSet closed
The problem in the code is that we cannot close the statement instance before we are done with Resultset
. Once we are done with the Resultset
, we can close both Resultset
and Statement Instance.
As we can see, we are trying to print the Boolean from Result_Set.next()
, but we are using the Resultset
after closing the statement instance, which is also closing the Resultset
.
In the code above, the fix will be not to close the statement at this place or not to use the Resultset
after closing the statement instance. It is based on your application either we can remove the Demo_Statement.close()
or the System.out.println(Result_Set.next());
statement.
Code:
ResultSet Result_Set; // class variable
Statement Demo_Statement = null;
try{
Demo_Statement = DB_Connection.createStatement();
Result_Set = Demo_Statement.getGeneratedKeys();
}
catch (Exception e){
throw e;
}
finally{
try{
if (Demo_Statement != null)
Demo_Statement.close();
} catch (SQLException e){
throw e;
}
}
We just removed the part where we are trying the use the Resultset
after the statement instance is closed. Once all the operations are done with the Resultset
, we can close both the statement instance and Resultset
.
Код метода отрабатывает нормально, но еще и выводит «Operation not allowed after ResultSet closed». На stackoverflow есть такее вопросы и они уже решенные. Но я что-то не так делаю, и оно не работает
Код должен брать количество одного продукта из бд и увеличивать его на то количество, которое напишет пользователь. Как избавиться от «Operation not allowed after ResultSet closed»
Вообщем и целом, вот код:
if (searchedCategory) {
Statement statementUpdate = connection.createStatement();
sql = "select * from snacks where category='" + categoryFromUser + "'";
ResultSet rsUpdate = statementUpdate.executeQuery(sql);
// add an additional amount
while (rsUpdate.next()) {
int amountFromTable = rsUpdate.getInt("amount");
double priceFromTable = rsUpdate.getDouble("price");
String formattedPrice = String.format("%.2f", priceFromTable).replace(",", ".");
int amountRes = amountFromTable + amountFromUser;
sql = "update snacks " +
"set amount=" + amountRes + " where category='" + categoryFromUser + "'";
statementUpdate.executeUpdate(sql);
System.out.println(categoryFromUser + " " + formattedPrice + " " + amountRes);
}
rsUpdate.close();
statementUpdate.close();
} else {
System.out.println("There is no such category in the list :( n" +
"First, add your "" + categoryFromUser + "" using the addCategory command");
}
Как избавиться от «Operation not allowed after ResultSet closed»?
Ответы (2 шт):
Вот этот код надо убрать или перенести за цикл
sql = "update snacks " +
"set amount=" + amountRes + " where category='" + categoryFromUser + "'";
statementUpdate.executeUpdate(sql);
Нельзя использовать один и тот же statement для разных запросов одновременно. Сначала надо закрыть текущий, а потом только возможно переиспользовать его.
Можно создать новый statement, но лучше обновлять таблицу после ее чтения.
→ Ссылка
Автор решения: Roman Konoval
Лучше всего делать прямое изменение в БД, не вычитывая данные.
if (searchedCategory) {
String sql = "UPDATE snacks SET amount = amount + ? WHERE category = ?";
try (PreparedStatement updateStatement = connection.prepareStatement(sql)) {
updateStatement.setInt(1, amountFromUser);
updateStatement.setString(2, categoryFromUser);
updateStatement.executeUpdate();
}
}
Лучше использовать PreparedStatement
(как в коде выше) и не строить запрос вручную из кусочков текста, так как это опасно.
А ошибка возникает, скорее всего, на второй итерации цикла на шаге rsUpdate.next()
, т.к выполнение executeUpdate
закрывает существующий ResultSet.
→ Ссылка
Вы не должны передавать ResultSet
через общедоступные методы. Это подвержено утечке ресурсов, потому что вы вынуждены сохранять отчет и соединение открыто. Закрытие их неявно закрывает набор результатов. Но держать их открытыми приведет к тому, что они будут болтаться и заставить БД исчерпывать ресурсы, когда их слишком много.
Сопоставьте его с коллекцией Javabeans, как это, и верните его вместо:
public List<Biler> list() throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
List<Biler> bilers = new ArrayList<Biler>();
try {
connection = database.getConnection();
statement = connection.prepareStatement("SELECT id, name, value FROM Biler");
resultSet = statement.executeQuery();
while (resultSet.next()) {
Biler biler = new Biler();
biler.setId(resultSet.getLong("id"));
biler.setName(resultSet.getString("name"));
biler.setValue(resultSet.getInt("value"));
bilers.add(biler);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return bilers;
}
Или, если вы уже на Java 7, просто используйте try-with-resources выражение, которое автоматически закрывает эти ресурсы
public List<Biler> list() throws SQLException {
List<Biler> bilers = new ArrayList<Biler>();
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, name, value FROM Biler");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Biler biler = new Biler();
biler.setId(resultSet.getLong("id"));
biler.setName(resultSet.getString("name"));
biler.setValue(resultSet.getInt("value"));
bilers.add(biler);
}
}
return bilers;
}
Кстати, вы не должны объявлять Connection
, Statement
и ResultSet
как переменные экземпляра вообще (основная проблема безопасности потоков!) и не проглатывать SQLException
в этой точке вообще ( вызывающий не будет знать, что возникла проблема), а также не закрывать ресурсы в том же try
(если, например, закрытие результата закрывает исключение, то инструкция и соединение все еще открыты). Все эти проблемы исправлены в приведенных выше фрагментах кода.
Answer by Brielle Ponce
The problem is with the way you fetch data in getStuff(). Each time you visit getStuff() you obtain a fresh ResultSet but you don’t close it. ,
Cool. I created a new Statement in getStuff() and that solved the problem.
– samxli
Apr 30 ’11 at 11:59
,
Can we tell which way AC power is going through a cable without cutting the cable?
,I guess after while(rs2.next()) you are trying to access something from rs1. But it’s already closed since you reexecuted statement to get rs2 from it. Since you didn’t close it, I beleive it’s used again below.
The problem is with the way you fetch data in getStuff()
. Each time you visit getStuff()
you obtain a fresh ResultSet
but you don’t close it.
getStuff()
The problem is with the way you fetch data in getStuff()
. Each time you visit getStuff()
you obtain a fresh ResultSet
but you don’t close it.
getStuff()
The problem is with the way you fetch data in getStuff()
. Each time you visit getStuff()
you obtain a fresh ResultSet
but you don’t close it.
ResultSet
Answer by Raelyn Burns
Page generated in 0.009 sec. using MySQL 8.0.26-commercial ,The file you have requested (bug.php?id=620)
does not exist., © 2021, Oracle Corporation and/or its affiliates
The file you have requested (bug.php?id=620
)
does not exist.
bug.php?id=620
Answer by Sky Pollard
Detect Loop in Linked List And Identify the Start …,Count Number of Words in the given input String,Shortest Distance in m x n Matrix from Source to D…,HackerRank Problem: Birthday Chocolate
ResultSet resultSet; // class variable
...
...
Statement st = null;
try {
st = conn.createStatement();
resultSet = st.getGeneratedKeys();
} catch (Exception e) {
throw e;
} finally {
try {
if (st != null) st.close();
} catch (SQLException e) {
throw e;
}
}
Answer by Amias Singh
Getting java.sql.SQLException: Operation not allowed after ResultSet closed ,Copyright © 2021 SemicolonWorld. All Rights Reserved. ,Bottom line: you have several ResultSet pertaining to the same Statement object concurrently opened.,What makes things even worse is the rs from the calling code. It is also derived off-of the statement field but it is not closed.
When I execute the following code, I get an exception. I think it is because I’m preparing in new statement with he same connection object. How should I rewrite this so that I can create a prepared statement AND get to use rs2? Do I have to create a new connection object even if the connection is to the same DB?
try
{
//Get some stuff
String name = "";
String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
name = rs.getString("name");
}
String sql2 = "SELECT `id` FROM `profiles` WHERE `id` =" + profId + ";";
ResultSet rs2 = statement.executeQuery(sql2);
String updateSql = "INSERT INTO `blah`............";
PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);
while(rs2.next())
{
int id = rs2.getInt("id");
int stuff = getStuff(id);
pst.setInt(1, stuff);
pst.addBatch();
}
pst.executeBatch();
}
catch (Exception e)
{
e.printStackTrace();
}
private int getStuff(int id)
{
try
{
String sql = "SELECT ......;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
return rs.getInt("something");
}
return -1;
}//code continues