This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 8e1f20ff43 Fix BZ 70269 - StatementCache regression with drivers that
report statements as not poolable (#1083)
8e1f20ff43 is described below
commit 8e1f20ff4379daaf0b33ee61905601c98281c59a
Author: Raphael Vullriede <[email protected]>
AuthorDate: Fri Oct 16 13:26:15 2026 +0200
Fix BZ 70269 - StatementCache regression with drivers that report
statements as not poolable (#1083)
https://bz.apache.org/bugzilla/show_bug.cgi?id=70269
Co-authored-by: Mark Thomas <[email protected]>
---
.../jdbc/pool/interceptor/StatementCache.java | 18 +++++++++++-
.../tomcat/jdbc/test/TestStatementCache.java | 32 ++++++++++++++++++++++
webapps/docs/changelog.xml | 8 ++++++
3 files changed, 57 insertions(+), 1 deletion(-)
diff --git
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
index d5a18adad0..a6a2db467a 100644
---
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
+++
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
@@ -63,6 +63,8 @@ public class StatementCache extends
StatementDecoratorInterceptor implements Sta
*/
protected static final String STATEMENT_CACHE_ATTR =
StatementCache.class.getName() + ".cache";
+ private static final String SET_POOLABLE = "setPoolable";
+
/**
* Default constructor.
*/
@@ -346,6 +348,11 @@ public class StatementCache extends
StatementDecoratorInterceptor implements Sta
* Cache key for this statement.
*/
CacheKey key;
+ /**
+ * Poolable hint set by the application. Tracked here as some drivers
+ * (e.g. H2) always return false from {@code isPoolable()}.
+ */
+ private boolean poolable = true;
/**
* Constructs a CachedStatement.
* @param parent the parent prepared statement
@@ -365,7 +372,7 @@ public class StatementCache extends
StatementDecoratorInterceptor implements Sta
proxy.setCacheKey(getCacheKey());
try {
// Only cache if statement has been marked as poolable and
not close on completion
- if (getDelegate().isPoolable() &&
!getDelegate().isCloseOnCompletion()) {
+ if (poolable && !getDelegate().isCloseOnCompletion()) {
// clear Resultset
ResultSet result = getDelegate().getResultSet();
if (result != null && !result.isClosed()) {
@@ -409,6 +416,15 @@ public class StatementCache extends
StatementDecoratorInterceptor implements Sta
delegate = null;
}
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
+ Object result = super.invoke(proxy, method, args);
+ if (compare(SET_POOLABLE, method)) {
+ poolable = ((Boolean) args[0]).booleanValue();
+ }
+ return result;
+ }
+
/**
* Forces immediate closure of this cached statement.
*/
diff --git
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestStatementCache.java
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestStatementCache.java
index b7c3e30295..994f350a75 100644
---
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestStatementCache.java
+++
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestStatementCache.java
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
import org.apache.tomcat.jdbc.pool.interceptor.StatementCache;
import org.apache.tomcat.jdbc.pool.interceptor.StatementCounterInterceptor;
+import org.apache.tomcat.jdbc.test.driver.Driver;
public class TestStatementCache extends DefaultTestCase {
@@ -112,6 +113,37 @@ public class TestStatementCache extends DefaultTestCase {
con.close();
}
+ @Test
+ public void testPreparedStatementCacheDriverNotPoolable() throws Exception
{
+ datasource.setDriverClassName(Driver.class.getName());
+ datasource.setUrl("jdbc:tomcat:test");
+ config(true,false,100);
+ Connection con = datasource.getConnection();
+ PreparedStatement ps1 = con.prepareStatement("select 1");
+ Assert.assertFalse(ps1.isPoolable());
+ ps1.close();
+ Assert.assertEquals(1,interceptor.getCacheSize().get());
+ con.close();
+ }
+
+ @Test
+ public void testPreparedStatementNotPoolable() throws Exception {
+ datasource.setDriverClassName(Driver.class.getName());
+ datasource.setUrl("jdbc:tomcat:test");
+ config(true,false,100);
+ Connection con = datasource.getConnection();
+ PreparedStatement ps1 = con.prepareStatement("select 1");
+ ps1.setPoolable(false);
+ ps1.close();
+ Assert.assertEquals(0,interceptor.getCacheSize().get());
+ PreparedStatement ps2 = con.prepareStatement("select 1");
+ ps2.setPoolable(false);
+ ps2.setPoolable(true);
+ ps2.close();
+ Assert.assertEquals(1,interceptor.getCacheSize().get());
+ con.close();
+ }
+
@Test
public void testStatementClose1() throws Exception {
init();
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6bc893d904..a436abc9ae 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -461,6 +461,14 @@
configuration. Pull request <pr>1084</pr> provided by Raphael
Vullriede.
(markt)
</fix>
+ <fix>
+ <bug>70269</bug>: Correct a regression in the change that reset the
+ properties of statements cached by the <code>StatementCache</code>
+ interceptor that meant no statements were cached when using JDBC
+ drivers, such as H2 and MariaDB Connector/J, that always report
+ statements as not poolable. Pull request <pr>1083</pr> provided by
+ Raphael Vullriede. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Other">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]