0

So i have a code like this:

public static void ispisiSvakuDruguKnjigu(){
            try{
                Connection conn = getConnection();
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery("select * from knjiga");
                while(true){
                    if(rs.next()){
                        System.out.println(rs.getString("id")+" "+rs.getString("naslov"));
                        rs.relative(2);
                    } else {
                        return;
                    }
                }
            } catch (Exception e){
                e.printStackTrace();
            }
        }

That we are doing in a class that reads every 2nd book from a MySQL database, it is working properly on the class that im watching but on my PC it is showing me error like this:

java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.

EDIT First of all i want to thank you all for anwsers, i am a late learner, and a very big beginner at Java. I have managed to test it out and fix the code for it to work as intended based on your anwsers. My confusion mainly came that the course im watching and my code were exactly the same and it worked for them without having to do what i did. Thank you all for the patience again and sorry for confusion.

i changed this:

 Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
randomuser123
  • 11
  • 1
  • 4
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Oct 25 '21 at 22:26
  • Please show the full stack trace of the exception, and give the versions of JDK, database and JDBC driver that you *and* the instrcutor are using. – tgdavies Oct 25 '21 at 22:28

3 Answers3

0

This is where it pays to READ THE JAVADOC

boolean relative​(int rows)

...

SQLException - if a database access error occurs; this method is called 
     on a closed result set or the result set type is TYPE_FORWARD_ONLY
...

Since:
   1.2
Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
-2

TYPE_FORWARD_ONLY means you can only move forward on the result set, not backward, so you get an exception when you try to go back with beforeFirst(). try using prepareStatement() like below:

pstat=con.prepareStatement("select * from knjiga");             
        rs=pstat.executeQuery();
        int rowCount=0;

        while(rs.next())
        {
           System.out.println(rs.getString("id")+" "+rs.getString("naslov"));
                        
        }
Deepak Jain
  • 347
  • 1
  • 6
-2

Any ResultSet can theoretically go backwards, forwards, to the start, to the end, and to any position you please. At least, it has methods for all of that.

Unfortunately, actually 'delivering' on this promised functionality is pricey. So pricey, in fact, that you can tell a ResultSet that you'd like it to renege on these promises and instead save memory and the like.

That's what has happened here: You have a forward-only resultset. Of all the methods that navigate you row to row, only .next() works properly, and all others throw that exception.

It's a tad odd, as relative(1) means "move 1 row forward", which is exactly the same as what next() does, however, next() works and is guaranteed to, and any JDBC driver is free to fail on relative(1).

However, form the way you wrote your question it sounds like you aren't realizing that .relative(1) and .next() are identical in meaning (and only not identical in practice because there are configurations where .next() works as normal, and relative(1) throws.

Therefore, most likely the fix is: Re-read the docs, and familiarize yourself with what these methods do; you must have misunderstood before.

But, if you are just toying around (to be clear, .relative(1) should never be written. .next() is how you should write that), just for learning purposes, you have two options:

  1. Configure the ResultSet to be fully navigable. This is generally called a 'scrollable result set'. con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, "theSql") would do that. I don't recommend this, though - generally just write the code so that scrolling is not neccessary.

  2. Just call .next() instead.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72