Author: steve.ebersole(a)jboss.com
Date: 2007-01-19 10:14:43 -0500 (Fri, 19 Jan 2007)
New Revision: 11067
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/connection/C3P0ConnectionProvider.java
Log:
HHH-2371 : enhancements to C3P0ConnectionProvider (patch)
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/connection/C3P0ConnectionProvider.java
===================================================================
---
branches/Branch_3_2/Hibernate3/src/org/hibernate/connection/C3P0ConnectionProvider.java 2007-01-19
15:14:31 UTC (rev 11066)
+++
branches/Branch_3_2/Hibernate3/src/org/hibernate/connection/C3P0ConnectionProvider.java 2007-01-19
15:14:43 UTC (rev 11067)
@@ -3,13 +3,14 @@
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.Iterator;
import java.util.Properties;
import javax.sql.DataSource;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import com.mchange.v2.c3p0.PoolConfig;
import com.mchange.v2.c3p0.DataSources;
import org.hibernate.HibernateException;
@@ -20,120 +21,198 @@
/**
* A connection provider that uses a C3P0 connection pool. Hibernate will use this by
* default if the <tt>hibernate.c3p0.*</tt> properties are set.
+ *
+ * @author various people
* @see ConnectionProvider
- * @author various people
*/
public class C3P0ConnectionProvider implements ConnectionProvider {
+ private static final Log log = LogFactory.getLog( C3P0ConnectionProvider.class );
+
+ //swaldman 2006-08-28: define c3p0-style configuration parameters for properties with
+ // hibernate-specific overrides to detect and warn about
conflicting
+ // declarations
+ private final static String C3P0_STYLE_MIN_POOL_SIZE = "c3p0.minPoolSize";
+ private final static String C3P0_STYLE_MAX_POOL_SIZE = "c3p0.maxPoolSize";
+ private final static String C3P0_STYLE_MAX_IDLE_TIME = "c3p0.maxIdleTime";
+ private final static String C3P0_STYLE_MAX_STATEMENTS = "c3p0.maxStatements";
+ private final static String C3P0_STYLE_ACQUIRE_INCREMENT =
"c3p0.acquireIncrement";
+ private final static String C3P0_STYLE_IDLE_CONNECTION_TEST_PERIOD =
"c3p0.idleConnectionTestPeriod";
+ private final static String C3P0_STYLE_TEST_CONNECTION_ON_CHECKOUT =
"c3p0.testConnectionOnCheckout";
+
+ //swaldman 2006-08-28: define c3p0-style configuration parameters for initialPoolSize,
which
+ // hibernate sensibly lets default to minPoolSize, but we'll let
users
+ // override it with the c3p0-style property if they want.
+ private final static String C3P0_STYLE_INITIAL_POOL_SIZE =
"c3p0.initialPoolSize";
+
private DataSource ds;
private Integer isolation;
private boolean autocommit;
- private static final Log log = LogFactory.getLog(C3P0ConnectionProvider.class);
-
+ /**
+ * {@inheritDoc}
+ */
public Connection getConnection() throws SQLException {
final Connection c = ds.getConnection();
- if (isolation!=null) c.setTransactionIsolation( isolation.intValue() );
- if ( c.getAutoCommit()!=autocommit ) c.setAutoCommit(autocommit);
+ if ( isolation != null ) {
+ c.setTransactionIsolation( isolation.intValue() );
+ }
+ if ( c.getAutoCommit() != autocommit ) {
+ c.setAutoCommit( autocommit );
+ }
return c;
}
+ /**
+ * {@inheritDoc}
+ */
public void closeConnection(Connection conn) throws SQLException {
conn.close();
}
+ /**
+ * {@inheritDoc}
+ */
public void configure(Properties props) throws HibernateException {
- String jdbcDriverClass = props.getProperty(Environment.DRIVER);
- String jdbcUrl = props.getProperty(Environment.URL);
- Properties connectionProps = ConnectionProviderFactory.getConnectionProperties(props);
+ String jdbcDriverClass = props.getProperty( Environment.DRIVER );
+ String jdbcUrl = props.getProperty( Environment.URL );
+ Properties connectionProps = ConnectionProviderFactory.getConnectionProperties( props
);
log.info( "C3P0 using driver: " + jdbcDriverClass + " at URL: " +
jdbcUrl );
- log.info( "Connection properties: " +
PropertiesHelper.maskOut(connectionProps, "password") );
-
- autocommit = PropertiesHelper.getBoolean(Environment.AUTOCOMMIT, props);
- log.info("autocommit mode: " + autocommit);
+ log.info( "Connection properties: " + PropertiesHelper.maskOut(
connectionProps, "password" ) );
- if (jdbcDriverClass==null) {
- log.warn("No JDBC Driver class was specified by property " +
Environment.DRIVER);
+ autocommit = PropertiesHelper.getBoolean( Environment.AUTOCOMMIT, props );
+ log.info( "autocommit mode: " + autocommit );
+
+ if ( jdbcDriverClass == null ) {
+ log.warn( "No JDBC Driver class was specified by property " +
Environment.DRIVER );
}
else {
try {
- Class.forName(jdbcDriverClass);
+ Class.forName( jdbcDriverClass );
}
- catch (ClassNotFoundException cnfe) {
+ catch ( ClassNotFoundException cnfe ) {
try {
- ReflectHelper.classForName(jdbcDriverClass);
+ ReflectHelper.classForName( jdbcDriverClass );
}
- catch (ClassNotFoundException e) {
+ catch ( ClassNotFoundException e ) {
String msg = "JDBC Driver class not found: " + jdbcDriverClass;
- log.fatal(msg, e);
- throw new HibernateException(msg, e);
+ log.fatal( msg, e );
+ throw new HibernateException( msg, e );
}
}
}
try {
- int minPoolSize = PropertiesHelper.getInt(Environment.C3P0_MIN_SIZE, props, 1);
- int maxPoolSize = PropertiesHelper.getInt(Environment.C3P0_MAX_SIZE, props, 100);
- int maxIdleTime = PropertiesHelper.getInt(Environment.C3P0_TIMEOUT, props, 0);
- int maxStatements = PropertiesHelper.getInt(Environment.C3P0_MAX_STATEMENTS, props,
0);
- int acquireIncrement = PropertiesHelper.getInt(Environment.C3P0_ACQUIRE_INCREMENT,
props, 1);
- int idleTestPeriod = PropertiesHelper.getInt(Environment.C3P0_IDLE_TEST_PERIOD, props,
0);
+ //swaldman 2004-02-07: modify to allow null values to signify fall through to c3p0
PoolConfig defaults
+ Integer minPoolSize = PropertiesHelper.getInteger( Environment.C3P0_MIN_SIZE, props
);
+ Integer maxPoolSize = PropertiesHelper.getInteger( Environment.C3P0_MAX_SIZE, props
);
+ Integer maxIdleTime = PropertiesHelper.getInteger( Environment.C3P0_TIMEOUT, props );
+ Integer maxStatements = PropertiesHelper.getInteger( Environment.C3P0_MAX_STATEMENTS,
props );
+ Integer acquireIncrement = PropertiesHelper.getInteger(
Environment.C3P0_ACQUIRE_INCREMENT, props );
+ Integer idleTestPeriod = PropertiesHelper.getInteger(
Environment.C3P0_IDLE_TEST_PERIOD, props );
- PoolConfig pcfg = new PoolConfig();
- pcfg.setInitialPoolSize(minPoolSize);
- pcfg.setMinPoolSize(minPoolSize);
- pcfg.setMaxPoolSize(maxPoolSize);
- pcfg.setAcquireIncrement(acquireIncrement);
- pcfg.setMaxIdleTime(maxIdleTime);
- pcfg.setMaxStatements(maxStatements);
- pcfg.setIdleConnectionTestPeriod(idleTestPeriod);
+ Properties c3props = new Properties();
+ // turn hibernate.c3p0.* into c3p0.*, so c3p0
+ // gets a chance to see all hibernate.c3p0.*
+ for ( Iterator ii = props.keySet().iterator(); ii.hasNext(); ) {
+ String key = ( String ) ii.next();
+ if ( key.startsWith( "hibernate.c3p0." ) ) {
+ String newKey = key.substring( 10 );
+ if ( props.containsKey( newKey ) ) {
+ warnPropertyConflict( key, newKey );
+ }
+ c3props.put( newKey, props.get( key ) );
+ }
+ }
+
+ setOverwriteProperty( Environment.C3P0_MIN_SIZE, C3P0_STYLE_MIN_POOL_SIZE, props,
c3props, minPoolSize );
+ setOverwriteProperty( Environment.C3P0_MAX_SIZE, C3P0_STYLE_MAX_POOL_SIZE, props,
c3props, maxPoolSize );
+ setOverwriteProperty( Environment.C3P0_TIMEOUT, C3P0_STYLE_MAX_IDLE_TIME, props,
c3props, maxIdleTime );
+ setOverwriteProperty(
+ Environment.C3P0_MAX_STATEMENTS, C3P0_STYLE_MAX_STATEMENTS, props, c3props,
maxStatements
+ );
+ setOverwriteProperty(
+ Environment.C3P0_ACQUIRE_INCREMENT, C3P0_STYLE_ACQUIRE_INCREMENT, props, c3props,
acquireIncrement
+ );
+ setOverwriteProperty(
+ Environment.C3P0_IDLE_TEST_PERIOD, C3P0_STYLE_IDLE_CONNECTION_TEST_PERIOD, props,
c3props, idleTestPeriod
+ );
+
+ // revert to traditional hibernate behavior of setting initialPoolSize to minPoolSize
+ // unless otherwise specified with a c3p0.*-style parameter.
+ Integer initialPoolSize = PropertiesHelper.getInteger( C3P0_STYLE_INITIAL_POOL_SIZE,
props );
+ if ( initialPoolSize == null && minPoolSize != null ) {
+ c3props.put( C3P0_STYLE_INITIAL_POOL_SIZE, String.valueOf( minPoolSize ).trim() );
+ }
+
/*DataSource unpooled = DataSources.unpooledDataSource(
jdbcUrl, props.getProperty(Environment.USER), props.getProperty(Environment.PASS)
);*/
- DataSource unpooled = DataSources.unpooledDataSource(jdbcUrl, connectionProps);
- ds = DataSources.pooledDataSource(unpooled, pcfg);
+ DataSource unpooled = DataSources.unpooledDataSource( jdbcUrl, connectionProps );
+ Properties allProps = ( Properties ) props.clone();
+ allProps.putAll( c3props );
+
+ ds = DataSources.pooledDataSource( unpooled, allProps );
}
- catch (Exception e) {
- log.fatal("could not instantiate C3P0 connection pool", e);
+ catch ( Exception e ) {
+ log.fatal( "could not instantiate C3P0 connection pool", e );
throw new HibernateException( "Could not instantiate C3P0 connection pool",
e );
}
- String i = props.getProperty(Environment.ISOLATION);
- if (i==null) {
- isolation=null;
+ String i = props.getProperty( Environment.ISOLATION );
+ if ( i == null ) {
+ isolation = null;
}
else {
- isolation = new Integer(i);
- log.info("JDBC isolation level: " + Environment.isolationLevelToString(
isolation.intValue() ) );
+ isolation = new Integer( i );
+ log.info( "JDBC isolation level: " + Environment.isolationLevelToString(
isolation.intValue() ) );
}
}
+ /**
+ * {@inheritDoc}
+ */
public void close() {
try {
- DataSources.destroy(ds);
+ DataSources.destroy( ds );
}
- catch (SQLException sqle) {
- log.warn("could not destroy C3P0 connection pool", sqle);
+ catch ( SQLException sqle ) {
+ log.warn( "could not destroy C3P0 connection pool", sqle );
}
}
/**
- * @see ConnectionProvider#supportsAggressiveRelease()
+ * {@inheritDoc}
*/
public boolean supportsAggressiveRelease() {
return false;
}
+ private void setOverwriteProperty(String hibernateStyleKey, String c3p0StyleKey,
Properties hibp, Properties c3p, Integer value) {
+ if ( value != null ) {
+ c3p.put( c3p0StyleKey, String.valueOf( value ).trim() );
+ if ( hibp.getProperty( c3p0StyleKey ) != null ) {
+ warnPropertyConflict( hibernateStyleKey, c3p0StyleKey );
+ }
+ String longC3p0StyleKey = "hibernate." + c3p0StyleKey;
+ if ( hibp.getProperty( longC3p0StyleKey ) != null ) {
+ warnPropertyConflict( hibernateStyleKey, longC3p0StyleKey );
+ }
+ }
+ }
+
+ private void warnPropertyConflict(String hibernateStyle, String c3p0Style) {
+ log.warn(
+ "Both hibernate-style property '" + hibernateStyle +
+ "' and c3p0-style property '" + c3p0Style +
+ "' have been set in hibernate.properties. " +
+ "Hibernate-style property '" + hibernateStyle + "' will be
used " +
+ "and c3p0-style property '" + c3p0Style + "' will be
ignored!"
+ );
+ }
}
-
-
-
-
-
-
-