sushibrain
sushibrain

Reputation: 2790

HikariCP Connection leak

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

Answers (1)

brettw
brettw

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

Related Questions