/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.dbcp2.cpdsadapter;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Vector;

import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.PooledConnection;
import javax.sql.StatementEventListener;

import org.apache.commons.dbcp2.DelegatingConnection;
import org.apache.commons.dbcp2.DelegatingPreparedStatement;
import org.apache.commons.dbcp2.Jdbc41Bridge;
import org.apache.commons.dbcp2.PStmtKey;
import org.apache.commons.dbcp2.PoolableCallableStatement;
import org.apache.commons.dbcp2.PoolablePreparedStatement;
import org.apache.commons.dbcp2.PoolingConnection.StatementType;
import org.apache.commons.pool2.KeyedObjectPool;
import org.apache.commons.pool2.KeyedPooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

Implementation of PooledConnection that is returned by PooledConnectionDataSource.
Since:2.0
/** * Implementation of PooledConnection that is returned by PooledConnectionDataSource. * * @since 2.0 */
class PooledConnectionImpl implements PooledConnection, KeyedPooledObjectFactory<PStmtKey, DelegatingPreparedStatement> { private static final String CLOSED = "Attempted to use PooledConnection after closed() was called.";
The JDBC database connection that represents the physical db connection.
/** * The JDBC database connection that represents the physical db connection. */
private Connection connection;
A DelegatingConnection used to create a PoolablePreparedStatementStub.
/** * A DelegatingConnection used to create a PoolablePreparedStatementStub. */
private final DelegatingConnection<?> delegatingConnection;
The JDBC database logical connection.
/** * The JDBC database logical connection. */
private Connection logicalConnection;
ConnectionEventListeners.
/** * ConnectionEventListeners. */
private final Vector<ConnectionEventListener> eventListeners;
StatementEventListeners.
/** * StatementEventListeners. */
private final Vector<StatementEventListener> statementEventListeners = new Vector<>();
Flag set to true, once close() is called.
/** * Flag set to true, once {@link #close()} is called. */
private boolean closed;
My pool of PreparedStatements.
/** My pool of {@link PreparedStatement}s. */
private KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pStmtPool;
Controls access to the underlying connection.
/** * Controls access to the underlying connection. */
private boolean accessToUnderlyingConnectionAllowed;
Wraps the real connection.
Params:
  • connection – the connection to be wrapped.
/** * Wraps the real connection. * * @param connection * the connection to be wrapped. */
PooledConnectionImpl(final Connection connection) { this.connection = connection; if (connection instanceof DelegatingConnection) { this.delegatingConnection = (DelegatingConnection<?>) connection; } else { this.delegatingConnection = new DelegatingConnection<>(connection); } eventListeners = new Vector<>(); closed = false; }
My KeyedPooledObjectFactory method for activating PreparedStatements.
Params:
  • key – Ignored.
  • pooledObject – Ignored.
/** * My {@link KeyedPooledObjectFactory} method for activating {@link PreparedStatement}s. * * @param key * Ignored. * @param pooledObject * Ignored. */
@Override public void activateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) throws Exception { pooledObject.getObject().activate(); }
{@inheritDoc}
/** * {@inheritDoc} */
@Override public void addConnectionEventListener(final ConnectionEventListener listener) { if (!eventListeners.contains(listener)) { eventListeners.add(listener); } } /* JDBC_4_ANT_KEY_BEGIN */ @Override public void addStatementEventListener(final StatementEventListener listener) { if (!statementEventListeners.contains(listener)) { statementEventListeners.add(listener); } } /* JDBC_4_ANT_KEY_END */
Throws an SQLException, if isClosed is true
/** * Throws an SQLException, if isClosed is true */
private void assertOpen() throws SQLException { if (closed) { throw new SQLException(CLOSED); } }
Closes the physical connection and marks this PooledConnection so that it may not be used to generate any more logical Connections.
Throws:
  • SQLException – Thrown when an error occurs or the connection is already closed.
/** * Closes the physical connection and marks this <code>PooledConnection</code> so that it may not be used to * generate any more logical <code>Connection</code>s. * * @throws SQLException * Thrown when an error occurs or the connection is already closed. */
@Override public void close() throws SQLException { assertOpen(); closed = true; try { if (pStmtPool != null) { try { pStmtPool.close(); } finally { pStmtPool = null; } } } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Cannot close connection (return to pool failed)", e); } finally { try { connection.close(); } finally { connection = null; } } }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
Returns:a PStmtKey for the given arguments.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @return a {@link PStmtKey} for the given arguments. */
protected PStmtKey createKey(final String sql) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull()); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • autoGeneratedKeys – A flag indicating whether auto-generated keys should be returned; one of Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS.
Returns:a key to uniquely identify a prepared statement.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param autoGeneratedKeys * A flag indicating whether auto-generated keys should be returned; one of * <code>Statement.RETURN_GENERATED_KEYS</code> or <code>Statement.NO_GENERATED_KEYS</code>. * @return a key to uniquely identify a prepared statement. */
protected PStmtKey createKey(final String sql, final int autoGeneratedKeys) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), autoGeneratedKeys); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • columnIndexes – An array of column indexes indicating the columns that should be returned from the inserted row or rows.
Returns:a key to uniquely identify a prepared statement.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param columnIndexes * An array of column indexes indicating the columns that should be returned from the inserted row or * rows. * @return a key to uniquely identify a prepared statement. */
protected PStmtKey createKey(final String sql, final int columnIndexes[]) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), columnIndexes); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • resultSetType – A result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE.
  • resultSetConcurrency – A concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE.
Returns:a key to uniquely identify a prepared statement.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param resultSetType * A result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. * @param resultSetConcurrency * A concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code>. * @return a key to uniquely identify a prepared statement. */
protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), resultSetType, resultSetConcurrency); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • resultSetType – a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE.
  • resultSetConcurrency – A concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE
  • resultSetHoldability – One of the following ResultSet constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT.
Returns:a key to uniquely identify a prepared statement.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param resultSetType * a result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. * @param resultSetConcurrency * A concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code> * @param resultSetHoldability * One of the following <code>ResultSet</code> constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>. * @return a key to uniquely identify a prepared statement. */
protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), resultSetType, resultSetConcurrency, resultSetHoldability); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • resultSetType – a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
  • resultSetConcurrency – A concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE.
  • resultSetHoldability – One of the following ResultSet constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT.
  • statementType – The SQL statement type, prepared or callable.
Returns:a key to uniquely identify a prepared statement.
Since:2.4.0
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param resultSetType * a result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code> * @param resultSetConcurrency * A concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code>. * @param resultSetHoldability * One of the following <code>ResultSet</code> constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>. * @param statementType * The SQL statement type, prepared or callable. * @return a key to uniquely identify a prepared statement. * @since 2.4.0 */
protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability, final StatementType statementType) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), resultSetType, resultSetConcurrency, resultSetHoldability, statementType); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • resultSetType – A result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE.
  • resultSetConcurrency – A concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE.
  • statementType – The SQL statement type, prepared or callable.
Returns:a key to uniquely identify a prepared statement.
Since:2.4.0
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param resultSetType * A result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. * @param resultSetConcurrency * A concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code>. * @param statementType * The SQL statement type, prepared or callable. * @return a key to uniquely identify a prepared statement. * @since 2.4.0 */
protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, final StatementType statementType) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), resultSetType, resultSetConcurrency, statementType); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • statementType – The SQL statement type, prepared or callable.
Returns:a key to uniquely identify a prepared statement.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param statementType * The SQL statement type, prepared or callable. * @return a key to uniquely identify a prepared statement. */
protected PStmtKey createKey(final String sql, final StatementType statementType) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), statementType); }
Creates a PStmtKey for the given arguments.
Params:
  • sql – The SQL statement.
  • columnNames – An array of column names indicating the columns that should be returned from the inserted row or rows.
Returns:a key to uniquely identify a prepared statement.
/** * Creates a {@link PStmtKey} for the given arguments. * * @param sql * The SQL statement. * @param columnNames * An array of column names indicating the columns that should be returned from the inserted row or rows. * @return a key to uniquely identify a prepared statement. */
protected PStmtKey createKey(final String sql, final String columnNames[]) { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), columnNames); }
My KeyedPooledObjectFactory method for destroying PreparedStatements.
Params:
/** * My {@link KeyedPooledObjectFactory} method for destroying {@link PreparedStatement}s. * * @param key * ignored * @param pooledObject * the wrapped {@link PreparedStatement} to be destroyed. */
@Override public void destroyObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) throws Exception { pooledObject.getObject().getInnermostDelegate().close(); }
Closes the physical connection and checks that the logical connection was closed as well.
/** * Closes the physical connection and checks that the logical connection was closed as well. */
@Override protected void finalize() throws Throwable { // Closing the Connection ensures that if anyone tries to use it, // an error will occur. try { connection.close(); } catch (final Exception ignored) { // ignore } // make sure the last connection is marked as closed if (logicalConnection != null && !logicalConnection.isClosed()) { throw new SQLException("PooledConnection was gc'ed, without its last Connection being closed."); } } private String getCatalogOrNull() { try { return connection == null ? null : connection.getCatalog(); } catch (final SQLException e) { return null; } } private String getSchemaOrNull() { try { return connection == null ? null : Jdbc41Bridge.getSchema(connection); } catch (final SQLException e) { return null; } }
Returns a JDBC connection.
Throws:
  • SQLException – if the connection is not open or the previous logical connection is still open
Returns:The database connection.
/** * Returns a JDBC connection. * * @return The database connection. * @throws SQLException * if the connection is not open or the previous logical connection is still open */
@Override public Connection getConnection() throws SQLException { assertOpen(); // make sure the last connection is marked as closed if (logicalConnection != null && !logicalConnection.isClosed()) { // should notify pool of error so the pooled connection can // be removed !FIXME! throw new SQLException("PooledConnection was reused, without its previous Connection being closed."); } // the spec requires that this return a new Connection instance. logicalConnection = new ConnectionImpl(this, connection, isAccessToUnderlyingConnectionAllowed()); return logicalConnection; }
Returns the value of the accessToUnderlyingConnectionAllowed property.
Returns:true if access to the underlying is allowed, false otherwise.
/** * Returns the value of the accessToUnderlyingConnectionAllowed property. * * @return true if access to the underlying is allowed, false otherwise. */
public synchronized boolean isAccessToUnderlyingConnectionAllowed() { return this.accessToUnderlyingConnectionAllowed; }
Params:
/** * My {@link KeyedPooledObjectFactory} method for creating {@link PreparedStatement}s. * * @param key * The key for the {@link PreparedStatement} to be created. */
@SuppressWarnings("resource") @Override public PooledObject<DelegatingPreparedStatement> makeObject(final PStmtKey key) throws Exception { if (null == key) { throw new IllegalArgumentException("Prepared statement key is null or invalid."); } if (key.getStmtType() == StatementType.PREPARED_STATEMENT) { final PreparedStatement statement = (PreparedStatement) key.createStatement(connection); @SuppressWarnings({"rawtypes", "unchecked" }) // Unable to find way to avoid this final PoolablePreparedStatement pps = new PoolablePreparedStatement(statement, key, pStmtPool, delegatingConnection); return new DefaultPooledObject<>(pps); } final CallableStatement statement = (CallableStatement) key.createStatement(connection); @SuppressWarnings("unchecked") final PoolableCallableStatement pcs = new PoolableCallableStatement(statement, key, pStmtPool, (DelegatingConnection<Connection>) delegatingConnection); return new DefaultPooledObject<>(pcs); }
Normalizes the given SQL statement, producing a canonical form that is semantically equivalent to the original.
Params:
  • sql – The SQL statement.
Returns:the normalized SQL statement.
/** * Normalizes the given SQL statement, producing a canonical form that is semantically equivalent to the original. * @param sql * The SQL statement. * @return the normalized SQL statement. */
protected String normalizeSQL(final String sql) { return sql.trim(); }
Sends a connectionClosed event.
/** * Sends a connectionClosed event. */
void notifyListeners() { final ConnectionEvent event = new ConnectionEvent(this); final Object[] listeners = eventListeners.toArray(); for (final Object listener : listeners) { ((ConnectionEventListener) listener).connectionClosed(event); } }
My KeyedPooledObjectFactory method for passivating PreparedStatements. Currently invokes PreparedStatement.clearParameters.
Params:
/** * My {@link KeyedPooledObjectFactory} method for passivating {@link PreparedStatement}s. Currently invokes * {@link PreparedStatement#clearParameters}. * * @param key * ignored * @param pooledObject * a wrapped {@link PreparedStatement} */
@Override public void passivateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) throws Exception { @SuppressWarnings("resource") final DelegatingPreparedStatement dps = pooledObject.getObject(); dps.clearParameters(); dps.passivate(); }
Creates or obtains a CallableStatement from my pool.
Params:
  • sql – an SQL statement that may contain one or more '?' parameter placeholders. Typically this statement is specified using JDBC call escape syntax.
Throws:
  • SQLException – Thrown if a database access error occurs or this method is called on a closed connection.
Returns:a default CallableStatement object containing the pre-compiled SQL statement.
Since:2.4.0
/** * Creates or obtains a {@link CallableStatement} from my pool. * * @param sql * an SQL statement that may contain one or more '?' parameter placeholders. Typically this statement is * specified using JDBC call escape syntax. * @return a default <code>CallableStatement</code> object containing the pre-compiled SQL statement. * @exception SQLException * Thrown if a database access error occurs or this method is called on a closed connection. * @since 2.4.0 */
CallableStatement prepareCall(final String sql) throws SQLException { if (pStmtPool == null) { return connection.prepareCall(sql); } try { return (CallableStatement) pStmtPool.borrowObject(createKey(sql, StatementType.CALLABLE_STATEMENT)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareCall from pool failed", e); } }
Creates or obtains a CallableStatement from my pool.
Params:
  • sql – a String object that is the SQL statement to be sent to the database; may contain on or more '?' parameters.
  • resultSetType – a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE.
  • resultSetConcurrency – a concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE.
Throws:
  • SQLException – Thrown if a database access error occurs, this method is called on a closed connection or the given parameters are not ResultSet constants indicating type and concurrency.
Returns:a CallableStatement object containing the pre-compiled SQL statement that will produce ResultSet objects with the given type and concurrency.
Since:2.4.0
/** * Creates or obtains a {@link CallableStatement} from my pool. * * @param sql * a <code>String</code> object that is the SQL statement to be sent to the database; may contain on or * more '?' parameters. * @param resultSetType * a result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. * @param resultSetConcurrency * a concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code>. * @return a <code>CallableStatement</code> object containing the pre-compiled SQL statement that will produce * <code>ResultSet</code> objects with the given type and concurrency. * @throws SQLException * Thrown if a database access error occurs, this method is called on a closed connection or the given * parameters are not <code>ResultSet</code> constants indicating type and concurrency. * @since 2.4.0 */
CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { if (pStmtPool == null) { return connection.prepareCall(sql, resultSetType, resultSetConcurrency); } try { return (CallableStatement) pStmtPool.borrowObject( createKey(sql, resultSetType, resultSetConcurrency, StatementType.CALLABLE_STATEMENT)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareCall from pool failed", e); } }
Creates or obtains a CallableStatement from my pool.
Params:
  • sql – a String object that is the SQL statement to be sent to the database; may contain on or more '?' parameters.
  • resultSetType – one of the following ResultSet constants: ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE.
  • resultSetConcurrency – one of the following ResultSet constants: ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE.
  • resultSetHoldability – one of the following ResultSet constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT.
Throws:
  • SQLException – Thrown if a database access error occurs, this method is called on a closed connection or the given parameters are not ResultSet constants indicating type, concurrency, and holdability.
Returns:a new CallableStatement object, containing the pre-compiled SQL statement, that will generate ResultSet objects with the given type, concurrency, and holdability.
Since:2.4.0
/** * Creates or obtains a {@link CallableStatement} from my pool. * * @param sql * a <code>String</code> object that is the SQL statement to be sent to the database; may contain on or * more '?' parameters. * @param resultSetType * one of the following <code>ResultSet</code> constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. * @param resultSetConcurrency * one of the following <code>ResultSet</code> constants: <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code>. * @param resultSetHoldability * one of the following <code>ResultSet</code> constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>. * @return a new <code>CallableStatement</code> object, containing the pre-compiled SQL statement, that will * generate <code>ResultSet</code> objects with the given type, concurrency, and holdability. * @throws SQLException * Thrown if a database access error occurs, this method is called on a closed connection or the given * parameters are not <code>ResultSet</code> constants indicating type, concurrency, and holdability. * @since 2.4.0 */
CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { if (pStmtPool == null) { return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); } try { return (CallableStatement) pStmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency, resultSetHoldability, StatementType.CALLABLE_STATEMENT)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareCall from pool failed", e); } }
Creates or obtains a PreparedStatement from my pool.
Params:
  • sql – the SQL statement.
Returns:a PoolablePreparedStatement
/** * Creates or obtains a {@link PreparedStatement} from my pool. * * @param sql * the SQL statement. * @return a {@link PoolablePreparedStatement} */
PreparedStatement prepareStatement(final String sql) throws SQLException { if (pStmtPool == null) { return connection.prepareStatement(sql); } try { return pStmtPool.borrowObject(createKey(sql)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareStatement from pool failed", e); } }
Creates or obtains a PreparedStatement from my pool.
Params:
  • sql – an SQL statement that may contain one or more '?' IN parameter placeholders.
  • autoGeneratedKeys – a flag indicating whether auto-generated keys should be returned; one of Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS.
See Also:
Returns:a PoolablePreparedStatement
/** * Creates or obtains a {@link PreparedStatement} from my pool. * * @param sql * an SQL statement that may contain one or more '?' IN parameter placeholders. * @param autoGeneratedKeys * a flag indicating whether auto-generated keys should be returned; one of * <code>Statement.RETURN_GENERATED_KEYS</code> or <code>Statement.NO_GENERATED_KEYS</code>. * @return a {@link PoolablePreparedStatement} * @see Connection#prepareStatement(String, int) */
PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException { if (pStmtPool == null) { return connection.prepareStatement(sql, autoGeneratedKeys); } try { return pStmtPool.borrowObject(createKey(sql, autoGeneratedKeys)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareStatement from pool failed", e); } } PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException { if (pStmtPool == null) { return connection.prepareStatement(sql, columnIndexes); } try { return pStmtPool.borrowObject(createKey(sql, columnIndexes)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareStatement from pool failed", e); } }
Creates or obtains a PreparedStatement from my pool.
Params:
  • sql – a String object that is the SQL statement to be sent to the database; may contain one or more '?' IN parameters.
  • resultSetType – a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE.
  • resultSetConcurrency – a concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE.
See Also:
Returns:a PoolablePreparedStatement.
/** * Creates or obtains a {@link PreparedStatement} from my pool. * * @param sql * a <code>String</code> object that is the SQL statement to be sent to the database; may contain one or * more '?' IN parameters. * @param resultSetType * a result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. * @param resultSetConcurrency * a concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or * <code>ResultSet.CONCUR_UPDATABLE</code>. * * @return a {@link PoolablePreparedStatement}. * @see Connection#prepareStatement(String, int, int) */
PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { if (pStmtPool == null) { return connection.prepareStatement(sql, resultSetType, resultSetConcurrency); } try { return pStmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareStatement from pool failed", e); } } PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { if (pStmtPool == null) { return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); } try { return pStmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareStatement from pool failed", e); } } PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException { if (pStmtPool == null) { return connection.prepareStatement(sql, columnNames); } try { return pStmtPool.borrowObject(createKey(sql, columnNames)); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException("Borrow prepareStatement from pool failed", e); } }
{@inheritDoc}
/** * {@inheritDoc} */
@Override public void removeConnectionEventListener(final ConnectionEventListener listener) { eventListeners.remove(listener); } /* JDBC_4_ANT_KEY_BEGIN */ @Override public void removeStatementEventListener(final StatementEventListener listener) { statementEventListeners.remove(listener); } /* JDBC_4_ANT_KEY_END */
Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to the underlying connection. (Default: false.)
Params:
  • allow – Access to the underlying connection is granted when true.
/** * Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to * the underlying connection. (Default: false.) * * @param allow * Access to the underlying connection is granted when true. */
public synchronized void setAccessToUnderlyingConnectionAllowed(final boolean allow) { this.accessToUnderlyingConnectionAllowed = allow; } public void setStatementPool(final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> statementPool) { pStmtPool = statementPool; }
My KeyedPooledObjectFactory method for validating PreparedStatements.
Params:
  • key – Ignored.
  • pooledObject – Ignored.
Returns:true
/** * My {@link KeyedPooledObjectFactory} method for validating {@link PreparedStatement}s. * * @param key * Ignored. * @param pooledObject * Ignored. * @return {@code true} */
@Override public boolean validateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) { return true; }
Since:2.6.0
/** * @since 2.6.0 */
@Override public synchronized String toString() { final StringBuilder builder = new StringBuilder(super.toString()); builder.append("[connection="); builder.append(connection); builder.append(", delegatingConnection="); builder.append(delegatingConnection); builder.append(", logicalConnection="); builder.append(logicalConnection); builder.append(", eventListeners="); builder.append(eventListeners); builder.append(", statementEventListeners="); builder.append(statementEventListeners); builder.append(", closed="); builder.append(closed); builder.append(", pStmtPool="); builder.append(pStmtPool); builder.append(", accessToUnderlyingConnectionAllowed="); builder.append(accessToUnderlyingConnectionAllowed); builder.append("]"); return builder.toString(); } }