2

Hi I have this problem only in DB2, I am using plain jdbc to execute a simple query.
Then I fetch the ResultSet and, during the fetch of the result set, I call another method which in turn executes another query (opening and closing anoher ResultSet). When the control comes back to the caller my original ResultSet is closed, and this is really weird..
PS: the code I post below works correctly with Sql Server and even with DB2 express, but in the client environment (DB2 on Z/OS) with driver version 3.64.82 no.

..........
    PreparedStatement  pst=conn.prepareStatement(query);
    ResultSet rs=pst.executeQuery();

    while(rs.next()){
        System.out.println("Id:"+rs.getInt("ID"));
        System.out.println("ULTERIORE SPECIFICA   "+getUlterioreSpecifica(conn,rs.getInt("ID")));
        System.out.println("Desc: "+rs.getString("DESC"));
        System.out.println("ETA: "+rs.getInt("ETA"));

    }
    ........

//other method

    private static String getUlterioreSpecifica(Connection conn, int int1) throws Exception{

    String query="select ult_desc from specifica where id=?";
    String retVal="";
      PreparedStatement pst=conn.prepareStatement(query);
      pst.setInt(1, int1);
      ResultSet rs=pst.executeQuery();
      while(rs.next()){
          retVal=rs.getString(1);
      }
      rs.close();
      pst.close();
    return retVal;
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
csciandr
  • 132
  • 1
  • 2
  • 14
  • The sql-server tag is for Microsoft SQL Server, it makes no sense to tag a DB2 question with it. – Mark Rotteveel May 09 '15 at 07:42
  • Have you disabled autocommit on the connection? – Mark Rotteveel May 09 '15 at 07:42
  • No, I don't understand why I have to disable autocommit if I am only executing a simple query (select). Could you please explain it? Thanks a lot – csciandr May 09 '15 at 07:57
  • The answer that was just posted by kjaklik explains it. You don't have to disable autocommit, but driver behavior is influenced by it (especially as a lot of drivers close the cursor on commit and JDBC mandates that executing a new statement in auto commit, will commit a previous transaction automatically) – Mark Rotteveel May 09 '15 at 08:02

1 Answers1

6

You're probably working in autocommit mode, and probably default behaviour for this specific driver is to close result sets on commit.

so based on comments in How can I avoid ResultSet is closed exception in Java?

what you need to do is set ResultSet.HOLD_CURSORS_OVER_COMMIT when you create the statement.

Community
  • 1
  • 1
Kris Jaklik
  • 267
  • 1
  • 9
  • Hi, I will try as soon as I can. Just one firther question, I see in the example that I have to declare the external statement like this: Statement st1 = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); and then the internal one like this: Statement st2 = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); Is it correct? I mean as far as you know by upgrading the driver version to a newer one could solve my issue? – csciandr May 09 '15 at 08:17
  • external statement needs to have `ResultSet.HOLD_CURSORS_OVER_COMMIT`. Internal one can be created without any flags. Updating driver can help, but it is not an error in the driver, but valid behaviour for example to increase performance or to reduce db overheat – Kris Jaklik May 09 '15 at 08:23
  • Thank you, but I have to disable autocommit too, right? – csciandr May 09 '15 at 08:25
  • 1
    No, you either disable autocommit or you add this flag – Kris Jaklik May 09 '15 at 08:26
  • Thanks again, I'll let you know when I can test it on the client's environment! – csciandr May 09 '15 at 08:39
  • Hi I was thinking about another solution, if in the internal method I retake the connection from the datasource instead of using the other connection do you think it will also work? Thanks – csciandr May 09 '15 at 08:46
  • @user3265189 That would also work, but it is worse for performance and actually more complex. – Mark Rotteveel May 09 '15 at 08:49
  • I just tried using the ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT , but unfortunately I still have the same error. I am going to try to set autocommit=false and then explicitly committing after – csciandr May 11 '15 at 07:53
  • Sorry guys it was my fault I forgot to add this property everywhere. Thank you very very much!! – csciandr May 11 '15 at 08:10