Skip to content

Commit dcc7e8c

Browse files
new example to fix
1 parent 026a409 commit dcc7e8c

4 files changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package testSuite.classes.resultset_forward_error;
2+
import java.sql.PreparedStatement;
3+
import java.sql.ResultSet;
4+
5+
import liquidjava.specification.ExternalRefinementsFor;
6+
import liquidjava.specification.Refinement;
7+
8+
9+
@ExternalRefinementsFor("java.sql.Connection")
10+
public interface ConnectionRefinements {
11+
12+
// Default statements are forward-only: the produced ResultSet cannot scroll backwards.
13+
@Refinement("setBackwards(_) == false")
14+
PreparedStatement prepareStatement(String sql);
15+
16+
// Explicit type decides scrollability: only TYPE_FORWARD_ONLY forbids backward scrolling.
17+
@Refinement("resultSetType == ResultSet.TYPE_FORWARD_ONLY ? setBackwards(_) == false : setBackwards(_) == true")
18+
PreparedStatement prepareStatement(String sql, int resultSetType,
19+
int resultSetConcurrency);
20+
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package testSuite.classes.resultset_forward_error;
2+
3+
import java.sql.ResultSet;
4+
import java.sql.SQLException;
5+
6+
import liquidjava.specification.ExternalRefinementsFor;
7+
import liquidjava.specification.Ghost;
8+
import liquidjava.specification.Refinement;
9+
import liquidjava.specification.StateRefinement;
10+
import liquidjava.specification.StateSet;
11+
12+
13+
@Ghost("boolean setBackwards")
14+
@ExternalRefinementsFor("java.sql.PreparedStatement")
15+
public interface PreparedStatementRefinements {
16+
17+
// The ResultSet inherits the statement's scrollability: backward-capable statements
18+
// yield an allowsBackward ResultSet, forward-only statements yield an onlyForward one.
19+
@Refinement("setBackwards(this) ? allowsBackward(_) : onlyForward(_)")
20+
ResultSet executeQuery() throws SQLException;
21+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package testSuite.classes.resultset_forward_error;
2+
3+
4+
// SO 6367737 — "ResultSet: Exception: set type is TYPE_FORWARD_ONLY -- why?"
5+
// https://stackoverflow.com/questions/6367737
6+
// Counting rows by iterating, then calling rs.beforeFirst() to rewind and iterate
7+
// again. A default ResultSet is TYPE_FORWARD_ONLY, so the backward scroll throws:
8+
// java.sql.SQLException: Result set type is TYPE_FORWARD_ONLY
9+
// at ...JdbcOdbcResultSet.beforeFirst(...)
10+
// Kept as close to the question as possible; the SO lines are wrapped in a method
11+
// taking a Connection. Pure java.sql; compiles with no JDBC driver present.
12+
import java.sql.Connection;
13+
import java.sql.PreparedStatement;
14+
import java.sql.ResultSet;
15+
import java.sql.SQLException;
16+
17+
public class ResultSetBeforeFirstOnForwardOnly {
18+
19+
int login(Connection con, String username, String password) throws SQLException {
20+
int typeID = 0;
21+
22+
PreparedStatement pstat =
23+
con.prepareStatement("select typeid from users where username=? and password=?");
24+
ResultSet rs = pstat.executeQuery();
25+
26+
// The default ResultSet is TYPE_FORWARD_ONLY, so the next line cannot rewind:
27+
// beforeFirst() requires a scrollable (allowsBackward) ResultSet.
28+
// FIX (accepted answers): request a scrollable result set, e.g.
29+
// con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
30+
// ResultSet.CONCUR_READ_ONLY);
31+
// or drop the rewind and read typeID inside the single forward pass.
32+
rs.beforeFirst(); // State Refinement Error
33+
34+
return typeID;
35+
}
36+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package testSuite.classes.resultset_forward_error;
2+
3+
import liquidjava.specification.ExternalRefinementsFor;
4+
import liquidjava.specification.StateRefinement;
5+
import liquidjava.specification.StateSet;
6+
7+
@StateSet({"onlyForward", "allowsBackward"})
8+
9+
@ExternalRefinementsFor("java.sql.ResultSet")
10+
public interface ResultSetRefinements {
11+
12+
boolean next();
13+
14+
float getFloat(String columnIndex);
15+
16+
@StateRefinement(from = "allowsBackward()")
17+
void beforeFirst();
18+
19+
}

0 commit comments

Comments
 (0)