Reputation: 23
I am building a 3-tier
application which uses java
classes for retrieving data from db
and jsp
pages for the user interface. When I try to call a method in a jsp page which returns resultset, I get this error message:
Operation not allowed after ResultSet closed.
For example, I have this method:
public ResultSet getName(String country) throws SQLException {
String name;
try {
open();
stmt1 = con.prepareStatement(fetchPanepistimio);
stmt1.setString(1,country);
rs1 = stmt1.executeQuery();
stmt1.close();
close();
}catch(Exception e2) {
}
return rs1;
}
and when I write in a jsp page the following:
<%
ResultSet rs = panepistimio.getName(country);
while(rs.next()) { %>
...........
<% } %>
I get the exception which I described. Have you got any idea about what is going wrong? Thank you in advance
Upvotes: 0
Views: 969
Reputation: 451
In your example, the ResultSet
is closed when you call stmt1.close()
. Perform your database access within the single method, add the results to an appropriate Collection
and return it.
For example:
public Collection<String> getName(String country) {
String sql = "...";
Collection<String> names = new ArrayList<>();
try(Statement statement = ...; ResultSet resultSet = statement.executeQuery(sql)){
while(resultSet.next()) {
names.add(resultSet.getString(...));
}
} catch (SQLException e) {
// LOG
}
return names;
}
Upvotes: 1
Reputation: 2108
This is because you're closing the PreparedStatement
object that created the ResultSet
immediately after executing the query (and potentially also closing the Connection
).
From the documentation for the Statement#close()
method (PreparedStatement
is a child of Statement
):
Releases this Statement object's database and JDBC resources immediately instead of waiting for this to happen when it is automatically closed. It is generally good practice to release resources as soon as you are finished with them to avoid tying up database resources.
Calling the method close on a Statement object that is already closed has no effect.
Note:When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
Emphasis mine.
Ideally you should materialise the contents of your ResultSet
into a formal collection and send that collection to the JSP instead of the ResultSet
.
Upvotes: 1
Reputation: 8200
You call close on the statement, which you should not.
Second, you should not swallow exeptions as in catch(Exception e2) {}
.
This makes it hard or impossible to trace errors.
Third, it is not good practise to iterate over a ResultSet
in a JSP. This should be done in the backend e.g. (in getName
). see How to avoid Java code in JSP files?
Upvotes: 0
Reputation: 76
You are trying to access the ResultSet after closing the database connection stmt1.close();
and close();
), which doesn't work that way. (see Oracle's tutorial for a longer explanation).
Instead of leaving the connection open, you should retrieve the content of the ResultSet
and then use it in your JSP page.
That way, you decouple the life cycle of the DB query from your view life cycle.
Upvotes: 2