PSQLException: This ResultSet is closed. - java

Im having this problem that I cant do a executeQuery and then a executeUpdate in the same method it gives me "PSQLException: This ResultSet is closed."
I have tried to create another statement and other ResultSet but with no success. I you have any Idea how you help me, I would appreciate it. Thanks
Statement stmt = pc.getStatement();
try
{
ResultSet rs = stmt.executeQuery("select * from artigos where
artigoc="+s);
while (rs.next())
{
int stock = rs.getInt("stock");
stmt.executeUpdate("update artigos set stock="+newStock+","
+ "vendidos="+newVendidos+" where artigoc="+s);
}
rs.close(); // muito importante depois da consulta!
} catch (Exception e) {
e.printStackTrace();
System.err.println("Problems retrieving data from db...");
}

The javadoc of Statement says:
All execution methods in the Statement interface implicitly close a current ResultSet object of the statement if an open one exists.
Use a different Statement object to execute the update.

Related

Resultset is empty when I close preparedStatement

I have such a method:
private static ResultSet select (Connection connection, String query) {
PreparedStatement selectQuery = null;
ResultSet resultSet = null;
try {
selectQuery = connection.prepareStatement(query);
resultSet = selectQuery.executeQuery();
selectQuery.close();
} catch (SQLException e) {
System.out.println(e);
}
return resultSet;
}
The thing is that the resultSet is always empty when I close the preparedStatement.
If I comment out the line with clothing preparedStatement //selectQuery.close(); everything is fine.
I close it after assigning value to the resultSet. So why it's empty?
A ResultSet is associated with an executed Statement. Close the statement and the resultset, with any data in it is cleared.
You need to process the resultset before you close the statement, so your approach will not work.
You have to iterate through the ResultSet. You have an high level example right here:
try{
// execute the query
ResultSet rs = st.executeQuery(query);
// iterate through the result set
while (rs.next())
{
// Replace with your data
int id = rs.getInt("id");
String name = rs.getString("name");
// do stuff with the result set, add to a List of objects (for example)
}
selectQuery.close();
}catch(SQLException e) {
System.out.println(e);
}
You have not to close the statement before having retrieved the data of the resultset otherwise these may be not accessible.
When you call this method, its ResultSet objects are closed.
So, only when you are finished using a Statement, call the Statement.close() method.
The close should be performed in a finally statement.
In this way you are ensure that you don't worry to wonder when close it.
With your actual code :
private static ResultSet select (Connection connection, String query) {
PreparedStatement selectQuery = null;
ResultSet resultSet = null;
try {
selectQuery = connection.prepareStatement(query);
resultSet = selectQuery.executeQuery();
} catch (SQLException e) {
System.out.println(e);
}
finally {
if (selectQuery != null) { selectQuery.close(); }
}
return resultSet;
}
}
A better alternative is using a try-with-resources statement :
try (Statement stmt = con.createStatement()) {
// ...
}
Because the javadoc says so:
Note: When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
Rationale: The stated behavior of Statement.close() is to release all resources. One of those resources is the server-side cursor for reading the results. But if you release that, then the ResultSet has nothing to pull data from.
I'm curious how you are determining that the (closed) ResultSet is "empty". It looks like all operations on a closed ResultSet (apart from close()) ought to throw an exception.

SQLEXCEPTION Operation not allowed after ResultSet closed error insist

Hello i need to do 2 active jobs with database in java.Firstly I did with 1 statement but after I read hints in here they said that I should use 2 statement.But although it still get Operation not allowed after ResultSet closed error.
try{
Class.forName("com.mysql.jdbc.Driver");
}
catch(ClassNotFoundException e){
System.err.println("Driver yok");
return;
}
Connection con=null;
try{
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/kutuphane","root","");
System.out.println("Veritabnı baglandıldı");
Statement stmt=con.createStatement();
String strSQL="UPDATE emanetler SET IADETARIH='"+strdate+"' WHERE KISIAD='"+jTextField1.getText()+"' "
Statement stmt2=con.createStatement();
stmt.execute(strSQL);
ResultSet rs=stmt2.executeQuery("SELECT * FROM kitaplar");
while(rs.next()){
if(rs.getString("KITAPAD").equals(jTextField2.getText())){
strSQL="UPDATE kitaplar SET KITAPADET="+rs.getInt("KITAPADET")+"+1 WHERE KITAPAD='"+jTextField2.getText()+"' ";
stmt2.execute(strSQL);
}
}
stmt.close();
stmt2.close();
}
catch(SQLException e){
System.out.println("Veritabanı baglanmadi");
e.printStackTrace();
}
First you are using stmt2 object
ResultSet rs=stmt2.executeQuery("SELECT * FROM kitaplar");
Then in while loop
strSQL="UPDATE kitaplar SET KITAPADET="+rs.getInt("KITAPADET")+"+1 WHERE KITAPAD='"+jTextField2.getText()+"' ";
stmt2.execute(strSQL);
This must be corrected to use a separate Statement Object in While Loop to execute queries.
Hope this helps

How to fix my Prepared Statement to give me data from the DB in my application?

I have my Java program and I need to get data from my MYSQL DB,
I wrote this one out but its just sysout so getting data from my class and not using the Prepared Statement (I can delete the first 3 lines and it will work the same )
Could use some help to figure out how to get data from my DB and print it out
public void viewClientDetails(ClientsBean client) {
try {
PreparedStatement ps = connect.getConnection().prepareStatement(
"SELECT * FROM mbank.clients WHERE client_id = ?");
ps.setLong(1, client.getClient_id());
System.out.println(client.getClient_id());
System.out.println(client.getName());
System.out.println(client.getType());
System.out.println(client.getPhone());
System.out.println(client.getAddress());
System.out.println(client.getEmail());
System.out.println(client.getComment());
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null,
"Problem occurs while trying to see client details");
}
}
Well you're not actually executing the prepared statement... you're just preparing it. You should call PreparedStatement.executeQuery and use the ResultSet it returns:
// ...code as before...
try (ResultSet results = ps.executeQuery()) {
while (results.next()) {
// Use results.getInt etc
}
}
(You should use a try-with-resources statement to close the PreparedStatement too - or a manual try/finally block if you're not using Java 7.)
You need to do executeQuery on the preparedstatement to get a result set back of the query you performed.
You are simply not executing the query. Add a PreparedStatement.executeQuery() call. And fetch the results from the returned ResultSet.
For example:
PreparedStatement ps = connect.getConnection().prepareStatement("SELECT * FROM mbank.clients WHERE client_id = ?");
ps.setLong(1, client.getClient_id());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String userid = rs.getString("id");
String username = rs.getString("name");
}
As #Jon Skeet pointed out, the declaration of ResultSet in Java 7 is updated to:
public interface ResultSet extends Wrapper, AutoCloseable
It is AutoClosable now, which means that you can and should use the try-with-resource pattern.
You can do the below.
PreparedStatement ps = connect.getConnection().prepareStatement(
"SELECT * FROM mbank.clients WHERE client_id = ?");
resultSet = ps.executeQuery();
while (resultSet.next()) {
String user = resultSet.getString("<COLUMN_1>");
String website = resultSet.getString("<COLUMN_2>");
String summary = resultSet.getString("<COLUMN_3>");
}

Operation not allowed after ResultSet closed

Allright been trying to figure this out the last 2 days.
Statement statement = con.createStatement();
String query = "SELECT * FROM sell";
ResultSet rs = query(query);
while (rs.next()){//<--- I get there operation error here
This is the query method.
public static ResultSet query(String s) throws SQLException {
try {
if (s.toLowerCase().startsWith("select")) {
if(stm == null) {
createConnection();
}
ResultSet rs = stm.executeQuery(s);
return rs;
} else {
if(stm == null) {
createConnection();
}
stm.executeUpdate(s);
}
return null;
} catch (Exception e) {
e.printStackTrace();
con = null;
stm = null;
}
return null;
}
How can I fix this error?
It's hard to be sure just from the code you've posted, but I suspect that the ResultSet is inadvertently getting closed (or stm is getting reused) inside the body of the while loop. This would trigger the exception at the start of the following iteration.
Additionally, you need to make sure there are no other threads in your application that could potentially be using the same DB connection or stm object.
IMHO, you should do everything you need with your ResultSet before you close your connection.
there are few things you need to fix. Opening a connection, running a query to get the rs, closing it, and closing the connection all should be done in the same function scope as far as possible. from your code, you seem to use the "con" variable as a global variable, which could potentially cause a problem. you are not closing the stm object. or the rs object. this code does not run for too long, even if it has no errors. Your code should be like this:
if (stringUtils.isBlank(sql)){
throw new IllegalArgumentsException ("SQL statement is required");
}
Connection con = null;
PreparedStatement ps =null;
Resultset rs = null;
try{
con = getConnection();
ps = con.preparestatement(sql);
rs = ps.executeQuery();
processResults(rs);
close(rs);
close(ps);
close(con);
}catch (Execption e){
log.Exception ("Error in: {}", sql, e);
throw new RuntimeException (e);
}finally{
close(rs);
close(ps);
close(con);
}
use another Statement object in inner loop
Like
Statement st,st1;
st=con.createStatement();
st1=con.createStatement();
//in Inner loop
while(<<your code>>)
{
st1.executeQuery(<<your query>>);
}
I know this is a few years late, but I've found that synchronizing the db methods usually get rid of this problem.

Is this jdbc resource closed?

Looking back over my code I find that I occasionaly have written:
ResultSet rs = conn.createStatement().executeQuery("select * from main");
//snip
rs.close();
and sometimes I've written
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("Select * from main");
//snip
rs.close();
st.close();
In the second code segment, it's more obvious that the Statement is closed, but is it also closed in the first one? conn.createStatement() returns a statement object, but when it's instantiated like that I don't see any easy way to close it after I'm done. Should I just rewrite the various bits of code to use method #2?
A good practice is to put the rs.close() and st.close() in your finally clause.
Statement st;
ResultSet rs;
try {
st = connection.createStatement(...);
rs = st.executeQuery();
}
catch (JdbcErrorsExceptionsAndFoo exception) {
// yadda yadda
}
finally {
if (rs!= null) {
rs.close();
}
if (st != null) {
st.close();
}
}
The Statement will be automatically closed when it is garbage collected, but you need to explicitly close it if you want to free the resources as soon as you're done with them.
Note, however, that the reverse actually does work. That is, closing a Statement also closes the ResultSet associated with it.
if statement contains a resultset, gc does not collect it. you can use the second method or use aspects or filters to auto close them.

Categories

Resources