Reputation: 2790
I'm working on a game that runs on a Java server. For database pooling I'm using HikariCP, which is a excellent library, but it is now throwing the following error my way:
[Hikari housekeeper (pool HikariPool-0)] WARN com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for connection com.mysql.jdbc.JDBC4Connection@5910e440, stack trace follows
java.lang.Exception: Apparent connection leak detected
at nl.finicky.lemonade.database.Database.prepare(Database.java:43)
at nl.finicky.lemonade.rooms.RoomFactory.loadRoom(RoomFactory.java:25)
at nl.finicky.lemonade.rooms.RoomFactory.<init>(RoomFactory.java:20)
at nl.finicky.lemonade.Lemonade.main(Lemonade.java:30)
Now I know that a connection leak means that an open connection is floating around somewhere, but I can't figure out how or where.
The following is a method in my database class, where the error should occur according to the stack trace.
public PreparedStatement prepare(String query) {
PreparedStatement statement = null;
try {
while (statement == null) {
statement = this.dataSource.getConnection().prepareStatement(query, 1);
// The line triggering the error ^
if (statement != null) {
this.databasePool.getStorage();
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
return statement;
}
}
This is just a basic method to initiate a statement. When this is called, I use it and then call resultSet.close()
, preparedStatement.getConnection.close()
and preparedStatement.close()
Still it tells me that the connection is open.
How do I solve this? Thanks!
Upvotes: 2
Views: 7938
Reputation: 11114
Calling preparedStatement.getConnection.close()
later will merely get a different connection and close it.
You can't do what you are trying to do with this kind of pattern. Calling this.dataSource.getConnection().prepareStatement(...)
is getting a Connection from the pool and throwing away the reference to it, after which nobody can close it. And you can't close the Connection in this method, even if you retained a reference to it, because then the returned PreparedStatement would be unusable.
Upvotes: 3