We're running a multi site app and trying to use MultiTenant switching between Schemas. We're able to switch between schemas, but it's popping up a statement leak warning about 30 seconds after a jdbc connection is made. The system is running on Payara(Glassfish 4) with Hibernate 5 and for the backend we're using Intersystems Cache as a datastore through a JDBC connection. The warning is probably being generated by a glassfish setting to find memory leaks. Our suspicion is that we're creating the connection or executing the statement improperly. The info on multi tenant functionality, in particular with schemas, seems to be more geared towards earlier versions of hibernate. Any suggestions are welcome.
Code:
public class MultiTenantSchemaConnectionProvider implements MultiTenantConnectionProvider {
private ConnectionProvider connectionProvider;
public MultiTenantSchemaConnectionProvider(){
connectionProvider = new DatasourceConnectionProviderImpl();
Configuration configuration = new Configuration().configure();
((DatasourceConnectionProviderImpl) connectionProvider)
.setJndiService(LazyHibernateServletFilter.getServiceRegistry().getService(JndiService.class));
((DatasourceConnectionProviderImpl) connectionProvider).configure(configuration.getProperties());
}
public Connection getAnyConnection() throws SQLException {
return connectionProvider.getConnection();
}
public Connection getConnection(String tenantIdentifier) throws SQLException {
Connection con = getAnyConnection();
try {
String tenantId = null;
if (tenantIdentifier.startsWith("192")) { // just for testing
tenantId = "testSchema1";
} else {
tenantId = "testSchema2";
}
con.createStatement().execute("USE DATABASE " + tenantId); // <----- Connection Leak Here
} catch (SQLException ex) {
ex.printStackTrace();
throw new HibernateException("Could not alter connection for specific schema");
}
return con;
}
@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
connection.close();
}
@Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
connection.close();
}
...
}
This is the error that's being generated.
Code:
2016-09-09T13:33:41.902-0700|Warning: A potential statement leak detected for connection pool CacheDb. The stack trace of the thread is provided below :
com.sun.gjc.spi.base.StatementWrapper.<init>(StatementWrapper.java:98)
com.sun.gjc.spi.jdbc40.StatementWrapper40.<init>(StatementWrapper40.java:64)
com.sun.gjc.spi.jdbc40.ConnectionWrapper40.createStatement(ConnectionWrapper40.java:75)
edu.ucdavis.vmth.vmacs.persistence.config.MultiTenantSchemaConnectionProvider2.getConnection(MultiTenantSchemaConnectionProvider2.java:69)
org.hibernate.internal.AbstractSessionImpl$ContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:429)
org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:84)
org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:109)
org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:47)
org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)