consistent handling of unwrap/isWrapperFor/isClosed in JDBC proxies

This commit is contained in:
Juergen Hoeller 2010-10-09 12:38:37 +00:00
parent 153680a5e6
commit be04aca037
4 changed files with 59 additions and 13 deletions

View File

@ -1295,7 +1295,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
/** /**
* Invocation handler that suppresses close calls on JDBC COnnections. * Invocation handler that suppresses close calls on JDBC Connections.
* Also prepares returned Statement (Prepared/CallbackStatement) objects. * Also prepares returned Statement (Prepared/CallbackStatement) objects.
* @see java.sql.Connection#close() * @see java.sql.Connection#close()
*/ */
@ -1310,11 +1310,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on ConnectionProxy interface coming in... // Invocation on ConnectionProxy interface coming in...
if (method.getName().equals("getTargetConnection")) { if (method.getName().equals("equals")) {
// Handle getTargetConnection method: return underlying Connection.
return this.target;
}
else if (method.getName().equals("equals")) {
// Only consider equal when proxies are identical. // Only consider equal when proxies are identical.
return (proxy == args[0]); return (proxy == args[0]);
} }
@ -1322,10 +1318,27 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
// Use hashCode of PersistenceManager proxy. // Use hashCode of PersistenceManager proxy.
return System.identityHashCode(proxy); return System.identityHashCode(proxy);
} }
else if (method.getName().equals("unwrap")) {
if (((Class) args[0]).isInstance(proxy)) {
return proxy;
}
}
else if (method.getName().equals("isWrapperFor")) {
if (((Class) args[0]).isInstance(proxy)) {
return true;
}
}
else if (method.getName().equals("close")) { else if (method.getName().equals("close")) {
// Handle close method: suppress, not valid. // Handle close method: suppress, not valid.
return null; return null;
} }
else if (method.getName().equals("isClosed")) {
return false;
}
else if (method.getName().equals("getTargetConnection")) {
// Handle getTargetConnection method: return underlying Connection.
return this.target;
}
// Invoke method on target Connection. // Invoke method on target Connection.
try { try {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -288,6 +288,16 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
// Connection has been fetched: use hashCode of Connection proxy. // Connection has been fetched: use hashCode of Connection proxy.
return System.identityHashCode(proxy); return System.identityHashCode(proxy);
} }
else if (method.getName().equals("unwrap")) {
if (((Class) args[0]).isInstance(proxy)) {
return proxy;
}
}
else if (method.getName().equals("isWrapperFor")) {
if (((Class) args[0]).isInstance(proxy)) {
return true;
}
}
else if (method.getName().equals("getTargetConnection")) { else if (method.getName().equals("getTargetConnection")) {
// Handle getTargetConnection method: return underlying connection. // Handle getTargetConnection method: return underlying connection.
return getTargetConnection(method); return getTargetConnection(method);
@ -344,14 +354,14 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
else if (method.getName().equals("clearWarnings")) { else if (method.getName().equals("clearWarnings")) {
return null; return null;
} }
else if (method.getName().equals("isClosed")) {
return this.closed;
}
else if (method.getName().equals("close")) { else if (method.getName().equals("close")) {
// Ignore: no target connection yet. // Ignore: no target connection yet.
this.closed = true; this.closed = true;
return null; return null;
} }
else if (method.getName().equals("isClosed")) {
return this.closed;
}
else if (this.closed) { else if (this.closed) {
// Connection proxy closed, without ever having fetched a // Connection proxy closed, without ever having fetched a
// physical JDBC Connection: throw corresponding SQLException. // physical JDBC Connection: throw corresponding SQLException.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -325,10 +325,23 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
// Use hashCode of Connection proxy. // Use hashCode of Connection proxy.
return System.identityHashCode(proxy); return System.identityHashCode(proxy);
} }
else if (method.getName().equals("unwrap")) {
if (((Class) args[0]).isInstance(proxy)) {
return proxy;
}
}
else if (method.getName().equals("isWrapperFor")) {
if (((Class) args[0]).isInstance(proxy)) {
return true;
}
}
else if (method.getName().equals("close")) { else if (method.getName().equals("close")) {
// Handle close method: don't pass the call on. // Handle close method: don't pass the call on.
return null; return null;
} }
else if (method.getName().equals("isClosed")) {
return false;
}
else if (method.getName().equals("getTargetConnection")) { else if (method.getName().equals("getTargetConnection")) {
// Handle getTargetConnection method: return underlying Connection. // Handle getTargetConnection method: return underlying Connection.
return this.target; return this.target;

View File

@ -196,8 +196,15 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource {
} }
return sb.toString(); return sb.toString();
} }
else if (method.getName().equals("isClosed")) { else if (method.getName().equals("unwrap")) {
return this.closed; if (((Class) args[0]).isInstance(proxy)) {
return proxy;
}
}
else if (method.getName().equals("isWrapperFor")) {
if (((Class) args[0]).isInstance(proxy)) {
return true;
}
} }
else if (method.getName().equals("close")) { else if (method.getName().equals("close")) {
// Handle close method: only close if not within a transaction. // Handle close method: only close if not within a transaction.
@ -205,6 +212,9 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource {
this.closed = true; this.closed = true;
return null; return null;
} }
else if (method.getName().equals("isClosed")) {
return this.closed;
}
if (this.target == null) { if (this.target == null) {
if (this.closed) { if (this.closed) {