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);
        }
    }
}

Reply via email to