Hi all,
Let me introduce myself, I'm one of the DBCP developers at Apache.
When I read the forum thread about your discontinuation of the hibernate DBCP integration I wondered why?
I can understand you don't want to support every connection pool out there but DBCP is a widely used pool and has a good track record for giving support/fixing bugs, but I'm a little biased of course ;-)
If there are problem with DBCP I would like to know. I follow the hibernate-dev list a little bit but DBCP support questions can always be sent to commons-(dev|user)@jakarta.apache.org for a certain response.
Looking at your jira issue list I see the most questions are about supporting new DBCP features. Attached you will find a new low maintenance DBCPConnectionProvider implementation.
Using the BasicDataSourceFactory you can easily create an implementation that automatically supports all new DBCP features.
Using ds = BasicDataSourceFactory.createDataSource(dbcpProperties);
This requires DBCP 1.2.x or higher.
All the current features/properties are supported:
http://jakarta.apache.org/commons/dbcp/configuration.html
and when DBCP 1.3 arrives you only have to replace the jar, no code changes for supporting the new properties/features!
I hope this will convince you not to drop DBCP support.
Best Regards Dirk Verbeeck
package org.hibernate.connection;
import java.sql.Connection; import java.sql.SQLException; import java.util.Iterator; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; import org.hibernate.cfg.Environment; /** * A connection provider that uses an Apache commons DBCP connection pool. Hibernate will * use this by default if the <tt>hibernate.dbcp.*</tt> properties are set. * * Supported properties: * http://jakarta.apache.org/commons/dbcp/configuration.html * * @see ConnectionProvider * @author various people */ public class DBCPConnectionProvider implements ConnectionProvider { private static final Log log = LogFactory.getLog(DBCPConnectionProvider.class); private static final String PREFIX = "hibernate.dbcp."; private DataSource ds; // Old Environment property for backward-compatibility public static final String DBCP_PS_MAXACTIVE = "hibernate.dbcp.ps.maxActive"; public void configure(Properties props) throws HibernateException { try { // DBCP properties used to create the BasicDataSource Properties dbcpProperties = new Properties(); // DriverClass & url String jdbcDriverClass = props.getProperty(Environment.DRIVER); String jdbcUrl = props.getProperty(Environment.URL); dbcpProperties.put("driverClassName", jdbcDriverClass); dbcpProperties.put("url", jdbcUrl); // Isolation level String isolationLevel = props.getProperty(Environment.ISOLATION); if (isolationLevel != null) { dbcpProperties.put("defaultTransactionIsolation", isolationLevel); } // Turn off autocommit dbcpProperties.put("defaultAutoCommit", String.valueOf(Boolean.FALSE)); // Copy all properties removing the prefix Properties connectionProps = ConnectionProviderFactory.getConnectionProperties(props); for (Iterator iter = connectionProps.keySet().iterator() ; iter.hasNext() ;) { String key = String.valueOf(iter.next()); if (key.startsWith(PREFIX)) { String property = key.substring(PREFIX.length()); String value = connectionProps.getProperty(key); dbcpProperties.put(property, value); } } // backward-compatibility if (connectionProps.getProperty(DBCP_PS_MAXACTIVE) == null) { log.info("DBCP prepared statement pooling disabled"); } else { log.info("DBCP prepared statement pooling enabled"); dbcpProperties.put("poolPreparedStatements", String.valueOf(Boolean.TRUE)); dbcpProperties.put("maxOpenPreparedStatements", connectionProps.getProperty(DBCP_PS_MAXACTIVE)); } // Let the factory create the pool ds = BasicDataSourceFactory.createDataSource(dbcpProperties); } catch (Exception e) { String message = "Could not create a DBCP pool"; log.fatal(message, e); throw new HibernateException(message, e); } } public Connection getConnection() throws SQLException { return ds.getConnection(); } public void closeConnection(Connection conn) throws SQLException { conn.close(); } public void close() throws HibernateException { try { if (ds instanceof BasicDataSource) { ((BasicDataSource) ds).close(); } else { log.warn("Couln't close an unknown datasource " + ds.getClass().getName()); } } catch (Exception e) { throw new HibernateException("Could not close DBCP pool", e); } } }