Connection pooling is one thing that needs to be done on a production server. Spring is becoming an extremely popular choice with Hibernate for its seamless integartion. But with Teneo, its a different ball-game altogether. Fortunately for us, Hibernate provides one such hook via the property in the Environment.CONNECTION_PROVIDER configuration. It takes in the name of a class implementing the interface ConnectionProvider.
I prefer the Apache Commons DBCP. You will find the example here. When configuring Teneo, you need to set:
Properties props = new Properties();
//this line is the killer: delegates the ConnectionProvider to our custom implementation
//look at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider()
props.put(Environment.CONNECTION_PROVIDER, MyConnectionProvider.class
.getName());
MyConnectionProvider.java looks like:
package com.swayam.teneo.config;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;
/**
*
* @author paawak
*/
public class MyConnectionProvider implements ConnectionProvider {
private DataSource ds;
public MyConnectionProvider() {
}
public void close() throws HibernateException {
// TODO Auto-generated method stub
}
public void closeConnection(Connection conn) throws SQLException {
conn.close();
}
public void configure(Properties props) throws HibernateException {
String jdbcDriver = (String) props.get(Environment.DRIVER);
if (jdbcDriver == null) {
throw new HibernateException(
"Please specify the JDBC driver with the key `Environment.DRIVER`");
}
// load the driver
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
throw new HibernateException(e);
}
String connectURI = (String) props.get(Environment.URL);
if (connectURI == null) {
throw new HibernateException(
"Please specify the connection URL with the key `Environment.URL`");
}
ds = setupDataSource(connectURI);
}
public Connection getConnection() throws SQLException {
return ds.getConnection();
}
public boolean supportsAggressiveRelease() {
// TODO Auto-generated method stub
return false;
}
/**
* refer to DBCP ManualPoolingDataSourceExample:
*
*
* http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/doc/ManualPoolingDataSourceExample.java?view=markup
*
*
* This is made static for de-coupling
*
*/
private static DataSource setupDataSource(String connectURI) {
//
// First, we'll need a ObjectPool that serves as the
// actual pool of connections.
//
// We'll use a GenericObjectPool instance, although
// any ObjectPool implementation will suffice.
//
ObjectPool connectionPool = new GenericObjectPool(null);
//
// Next, we'll create a ConnectionFactory that the
// pool will use to create Connections.
// We'll use the DriverManagerConnectionFactory,
// using the connect string passed in the command line
// arguments.
//
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
connectURI, null);
//
// Now we'll create the PoolableConnectionFactory, which wraps
// the "real" Connections created by the ConnectionFactory with
// the classes that implement the pooling functionality.
//
@SuppressWarnings("unused")
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
connectionFactory, connectionPool, null, null, false, true);
//
// Finally, we create the PoolingDriver itself,
// passing in the object pool we created.
//
PoolingDataSource dataSource = new PoolingDataSource(connectionPool);
return dataSource;
}
}