0

During analyze legacy part of project which I'm working at, I've found following method:

public int getCount(String tableName, Connection connection) throws SQLException {
    try (Statement statement = connection.createStatement();
         ResultSet resultSet = statement.executeQuery(
                 "SELECT COUNT (*) FROM " + tableName
         )) {
        return resultSet.getInt(1);
    }
}

In my mind, after query execution ResultSet has cursor before first row, and to move it, I should invoke some of navigation methods, like next(). And only then invoke getXXX() to obtain value of cell. From javadocs method next() summary

Moves the cursor forward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.

So, can anybody explain how it works here?

Oleg Zinoviev
  • 549
  • 3
  • 14
  • Can you please specify what part of that is unclear? – Joe C Mar 20 '18 at 21:21
  • @JoeC Unclear, how does getInt() obtain cell value without moving cursor from place "before the first row" to row itself – Oleg Zinoviev Mar 20 '18 at 21:24
  • You have to call resultSet.next() in order to move cursor. You don't seem to be doing that. Alternatively, you can call first(). – ATrubka Mar 20 '18 at 21:28
  • @ATrubka but this snippet works and returns correct result. And this embarrassed me – Oleg Zinoviev Mar 20 '18 at 21:31
  • 1
    That code *should* throw a `SQLException`, but perhaps the JDBC driver is lenient / *flawed* and returns values from first row, even though it shouldn't. --- *"Can anybody explain how it works here?"* No, because we don't know which JDBC driver you're using. – Andreas Mar 20 '18 at 21:33
  • 3
    I think what you are asking is clear. However, what is not clear is what implementation of ResultSet you are using. You are probably in the best position to answer "why it works" (despite the fact that an obvious interpretation of the javadoc is that it shouldn't work) by stepping into in a debugger and see why it works. – Rob Mar 20 '18 at 21:34
  • Are you sure you are looking in the right source code? Java [try catch syntax](https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html) is `try {...} catch (ExceptionType name) {...}` – Marmite Bomber Mar 20 '18 at 21:58
  • 1
    @MarmiteBomber: Java also has [try with resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html). – Luke Woodward Mar 20 '18 at 22:06
  • In this snippet try-with-resource construction is used and exception declared in exception list of method signature – Oleg Zinoviev Mar 20 '18 at 22:06
  • OK, sorry, I understood. Which DBMS is used? I Oracle 12.2 I get exception `java.sql.SQLException: ResultSet.next was not called` if the `rs.next()` is not called before the `getInt`. – Marmite Bomber Mar 20 '18 at 22:13
  • Result set doesn't move cursor. – Roman C Mar 20 '18 at 23:20
  • No real need to down vote or close. More appropriate title would be **Is in Java try with resources first next() call required while reading JDBC cursor**. [This question](https://stackoverflow.com/questions/8066501/how-should-i-use-try-with-resources-with-jdbc) suggest that the answer is YES. – Marmite Bomber Mar 21 '18 at 06:01
  • 1
    This shouldn't work, this behavior is explicitly disallowed by the JDBC specification and the API documentation. If it does work, it would indicate you're using a buggy JDBC driver, or something else up the call stack transforms the exception to something that looks like a correct result. As you don't specify the driver (+ its version) used, we can't possible help you. – Mark Rotteveel Mar 22 '18 at 20:01

0 Answers0