Reputation: 79
I have two static methods in two classes: Account and FunnyDB. in FunnyDB I have a method which is used in Account to retrieve object from database. I am wondering if it is possible to somehow close statement (stmt) in the FunnyDB from Account method. Also, if it is not really possible, what are the consequences of leaving statement not closed? These are my methods:
FunnyDB:
/**
* Returns ResultSet from query to get data to create object. Identufy data by id
*
* @param tableName Name of he table to search. Use getClass().getSimpleName().
* @param id
* @return
*/
public static ResultSet getObjectResultSetById(String tableName, int id) {
ResultSet rs = null;
try {
// gets object's details from database
Statement stmt = con.createStatement(); //<-- I WANT TO CLOSE THIS PARAMETER
String sql = "SELECT * \n"
+ "FROM " + tableName + " \n"
+ "WHERE " + tableName.toLowerCase() + "_id = " + id;
rs = stmt.executeQuery(sql);
//TODO: Closing rs and stmt? .close().
} catch (SQLException ex) {
Logger.getLogger(FunnyDB.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex.getMessage());
}
return rs;
}
Account:
/**
* Returns object found by given ID.
*
* @param id Object ID.
* @return Object from database.
*/
public static Account getAccountFromDatabaseById(int id) {
Account account = null;
try {
ResultSet rs = FunnyDB.getObjectResultSetById("Account", id);
// create object to return
while (rs.next()) {
account = new Account(rs.getInt("account_id"), rs.getString("account_name"), rs.getString("account_type"), Currency.getCurrencyFromDatabaseById(rs.getInt("currency_id")), rs.getDouble("start_amount"), rs.getDouble("balance"));
}
rs.close();
//close stmt?????
} catch (SQLException ex) {
Logger.getLogger(Currency.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex.getMessage());
}
return account;
}
Thank you for help
Upvotes: 1
Views: 164
Reputation: 178263
Making a class responsible for closing a Statement
that is different than the one that created it is a bad idea. What if the calling code forgets to close it?
The FunnyDB
class should be responsible for closing the Statement
; it created it. To do this, it must read the ResultSet
itself, creating the Account
, so that it's completely done with the ResultSet
. This way, there is no problem closing the ResultSet
and the Statement
before it returns.
Move the code that creates the Account
with calls to the ResultSet
into FunnyDB
's getObjectResultSetById
method. Have that method return the Account
instead of the ResultSet
. Close the ResultSet
and Statement
there. You might want to rename it getAccountById
. You may also want to use a "try with resources" statement if you're using Java 7+. You can have the ResultSet
and Statement
closed automatically. If you are stuck with Java 6 or below, use a finally
block to close
them, to ensure that everything is closed before returning.
The getAccountFromDatabaseById
in Account
doesn't need to manipulate the ResultSet
at all; it just needs to use the Account
returned by FunnyDB
.
Upvotes: 3
Reputation: 18242
You can pass the ResultSet as a parameter to getObjectResultSetById, so getAccountFromDatabaseById can close it.
Never EVER leave a resource open. When talking about databases, leaving a resource open could mean that at one point or another you will get a 'cursor limit exceeded' or something like that and this is hard to debug.
Also, as a general rule, always close your resources in a finally
block. This way, you ensure that your resources will be closed even if your method throws an exception.
Upvotes: 0