Operation not allowed after resultset closed ошибка

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's user avatar

wattostudios

8,65613 gold badges43 silver badges57 bronze badges

asked Jun 7, 2012 at 14:01

user1442387's user avatar

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

NPE's user avatar

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

iozee's user avatar

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.venigalla's user avatar

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>>);
}

Folkert van Heusden's user avatar

answered Jun 30, 2013 at 1:33

Saurabh Kachhia's user avatar

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

Zee's user avatar

ZeeZee

1,58212 silver badges26 bronze badges

0

  1. Java Error java.sql.SQLException: Operation not allowed after ResultSet closed
  2. Fix Java Error java.sql.SQLException: Operation not allowed after ResultSet closed

Java Error 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

Возможно, вам также будет интересно:

  • Operand should contain 1 column s ошибка
  • Opera ошибка сети при скачивании
  • Opera ошибка сертификата безопасности
  • Opera ошибка профиля при каждом запуске
  • Opera gx ошибка при запуске приложения 0xc0000142

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии