001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.dbcp2; 018 019import java.sql.CallableStatement; 020import java.sql.Connection; 021import java.sql.SQLException; 022 023import org.apache.commons.pool2.KeyedObjectPool; 024 025/** 026 * A {@link DelegatingCallableStatement} that cooperates with {@link PoolingConnection} to implement a pool of 027 * {@link CallableStatement}s. 028 * <p> 029 * The {@link #close} method returns this statement to its containing pool. (See {@link PoolingConnection}.) 030 * 031 * @see PoolingConnection 032 * @since 2.0 033 */ 034public class PoolableCallableStatement extends DelegatingCallableStatement { 035 036 /** 037 * The {@link KeyedObjectPool} from which this CallableStatement was obtained. 038 */ 039 private final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pool; 040 041 /** 042 * Key for this statement in the containing {@link KeyedObjectPool}. 043 */ 044 private final PStmtKey key; 045 046 /** 047 * Constructs a new instance. 048 * 049 * @param callableStatement 050 * the underlying {@link CallableStatement} 051 * @param key 052 * the key for this statement in the {@link KeyedObjectPool} 053 * @param pool 054 * the {@link KeyedObjectPool} from which this CallableStatement was obtained 055 * @param connection 056 * the {@link DelegatingConnection} that created this CallableStatement 057 */ 058 public PoolableCallableStatement(final CallableStatement callableStatement, final PStmtKey key, 059 final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pool, 060 final DelegatingConnection<Connection> connection) { 061 super(connection, callableStatement); 062 this.pool = pool; 063 this.key = key; 064 065 // Remove from trace now because this statement will be 066 // added by the activate method. 067 removeThisTrace(connection); 068 } 069 070 /** 071 * Activates after retrieval from the pool. Adds a trace for this CallableStatement to the Connection that created 072 * it. 073 * 074 * @since 2.4.0 made public, was protected in 2.3.0. 075 */ 076 @Override 077 public void activate() throws SQLException { 078 setClosedInternal(false); 079 AbandonedTrace.add(getConnectionInternal(), this); 080 super.activate(); 081 } 082 083 /** 084 * Returns the CallableStatement to the pool. If {{@link #isClosed()}, this is a No-op. 085 */ 086 @Override 087 public void close() throws SQLException { 088 // calling close twice should have no effect 089 if (!isClosed()) { 090 try { 091 pool.returnObject(key, this); 092 } catch (final SQLException | RuntimeException e) { 093 throw e; 094 } catch (final Exception e) { 095 throw new SQLException("Cannot close CallableStatement (return to pool failed)", e); 096 } 097 } 098 } 099 100 /** 101 * Passivates to prepare for return to the pool. Removes the trace associated with this CallableStatement from the 102 * Connection that created it. Also closes any associated ResultSets. 103 * 104 * @since 2.4.0 made public, was protected in 2.3.0. 105 */ 106 @Override 107 public void passivate() throws SQLException { 108 prepareToReturn(); 109 } 110 111}