HHH-7190 - Cache JDBC proxy class defintions
This commit is contained in:
parent
624855c438
commit
e24451637d
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc.internal.proxy;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a problem defining or instantiating a JDBC proxy class.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class JdbcProxyException extends HibernateException {
|
||||||
|
public JdbcProxyException(String message, Throwable root) {
|
||||||
|
super( message, root );
|
||||||
|
}
|
||||||
|
|
||||||
|
public JdbcProxyException(String message) {
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,9 @@
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc.internal.proxy;
|
package org.hibernate.engine.jdbc.internal.proxy;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
@ -33,6 +36,7 @@ import java.sql.Statement;
|
||||||
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
|
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcWrapper;
|
import org.hibernate.engine.jdbc.spi.JdbcWrapper;
|
||||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||||
|
import org.hibernate.internal.util.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Centralized builder for proxy instances
|
* Centralized builder for proxy instances
|
||||||
|
@ -48,14 +52,37 @@ public class ProxyBuilder {
|
||||||
JdbcWrapper.class
|
JdbcWrapper.class
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Connection buildConnection(LogicalConnectionImplementor logicalConnection) {
|
private static final Value<Constructor<Connection>> connectionProxyConstructorValue = new Value<Constructor<Connection>>(
|
||||||
ConnectionProxyHandler proxyHandler = new ConnectionProxyHandler( logicalConnection );
|
new Value.DeferredInitializer<Constructor<Connection>>() {
|
||||||
return ( Connection ) Proxy.newProxyInstance(
|
@Override
|
||||||
|
public Constructor<Connection> initialize() {
|
||||||
|
try {
|
||||||
|
return locateConnectionProxyClass().getConstructor( InvocationHandler.class );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Connection proxy class", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<Connection> locateConnectionProxyClass() {
|
||||||
|
return (Class<Connection>) Proxy.getProxyClass(
|
||||||
JdbcWrapper.class.getClassLoader(),
|
JdbcWrapper.class.getClassLoader(),
|
||||||
CONNECTION_PROXY_INTERFACES,
|
CONNECTION_PROXY_INTERFACES
|
||||||
proxyHandler
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Connection buildConnection(LogicalConnectionImplementor logicalConnection) {
|
||||||
|
final ConnectionProxyHandler proxyHandler = new ConnectionProxyHandler( logicalConnection );
|
||||||
|
try {
|
||||||
|
return connectionProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new JdbcProxyException( "Could not instantiate JDBC Connection proxy", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// Statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -66,20 +93,43 @@ public class ProxyBuilder {
|
||||||
InvalidatableWrapper.class
|
InvalidatableWrapper.class
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final Value<Constructor<Statement>> statementProxyConstructorValue = new Value<Constructor<Statement>>(
|
||||||
|
new Value.DeferredInitializer<Constructor<Statement>>() {
|
||||||
|
@Override
|
||||||
|
public Constructor<Statement> initialize() {
|
||||||
|
try {
|
||||||
|
return locateStatementProxyClass().getConstructor( InvocationHandler.class );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Statement proxy class", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<Statement> locateStatementProxyClass() {
|
||||||
|
return (Class<Statement>) Proxy.getProxyClass(
|
||||||
|
JdbcWrapper.class.getClassLoader(),
|
||||||
|
STMNT_PROXY_INTERFACES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
public static Statement buildStatement(
|
public static Statement buildStatement(
|
||||||
Statement statement,
|
Statement statement,
|
||||||
ConnectionProxyHandler connectionProxyHandler,
|
ConnectionProxyHandler connectionProxyHandler,
|
||||||
Connection connectionProxy) {
|
Connection connectionProxy) {
|
||||||
BasicStatementProxyHandler proxyHandler = new BasicStatementProxyHandler(
|
final BasicStatementProxyHandler proxyHandler = new BasicStatementProxyHandler(
|
||||||
statement,
|
statement,
|
||||||
connectionProxyHandler,
|
connectionProxyHandler,
|
||||||
connectionProxy
|
connectionProxy
|
||||||
);
|
);
|
||||||
return ( Statement ) Proxy.newProxyInstance(
|
try {
|
||||||
JdbcWrapper.class.getClassLoader(),
|
return statementProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
STMNT_PROXY_INTERFACES,
|
}
|
||||||
proxyHandler
|
catch (Exception e) {
|
||||||
);
|
throw new JdbcProxyException( "Could not instantiate JDBC Statement proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Statement buildImplicitStatement(
|
public static Statement buildImplicitStatement(
|
||||||
|
@ -89,12 +139,13 @@ public class ProxyBuilder {
|
||||||
if ( statement == null ) {
|
if ( statement == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ImplicitStatementProxyHandler handler = new ImplicitStatementProxyHandler( statement, connectionProxyHandler, connectionProxy );
|
final ImplicitStatementProxyHandler proxyHandler = new ImplicitStatementProxyHandler( statement, connectionProxyHandler, connectionProxy );
|
||||||
return ( Statement ) Proxy.newProxyInstance(
|
try {
|
||||||
JdbcWrapper.class.getClassLoader(),
|
return statementProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
STMNT_PROXY_INTERFACES,
|
}
|
||||||
handler
|
catch (Exception e) {
|
||||||
);
|
throw new JdbcProxyException( "Could not instantiate JDBC Statement proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,22 +157,45 @@ public class ProxyBuilder {
|
||||||
InvalidatableWrapper.class
|
InvalidatableWrapper.class
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final Value<Constructor<PreparedStatement>> preparedStatementProxyConstructorValue = new Value<Constructor<PreparedStatement>>(
|
||||||
|
new Value.DeferredInitializer<Constructor<PreparedStatement>>() {
|
||||||
|
@Override
|
||||||
|
public Constructor<PreparedStatement> initialize() {
|
||||||
|
try {
|
||||||
|
return locatePreparedStatementProxyClass().getConstructor( InvocationHandler.class );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Statement proxy class", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<PreparedStatement> locatePreparedStatementProxyClass() {
|
||||||
|
return (Class<PreparedStatement>) Proxy.getProxyClass(
|
||||||
|
JdbcWrapper.class.getClassLoader(),
|
||||||
|
PREPARED_STMNT_PROXY_INTERFACES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
public static PreparedStatement buildPreparedStatement(
|
public static PreparedStatement buildPreparedStatement(
|
||||||
String sql,
|
String sql,
|
||||||
Statement statement,
|
Statement statement,
|
||||||
ConnectionProxyHandler connectionProxyHandler,
|
ConnectionProxyHandler connectionProxyHandler,
|
||||||
Connection connectionProxy) {
|
Connection connectionProxy) {
|
||||||
PreparedStatementProxyHandler proxyHandler = new PreparedStatementProxyHandler(
|
final PreparedStatementProxyHandler proxyHandler = new PreparedStatementProxyHandler(
|
||||||
sql,
|
sql,
|
||||||
statement,
|
statement,
|
||||||
connectionProxyHandler,
|
connectionProxyHandler,
|
||||||
connectionProxy
|
connectionProxy
|
||||||
);
|
);
|
||||||
return ( PreparedStatement ) Proxy.newProxyInstance(
|
try {
|
||||||
JdbcWrapper.class.getClassLoader(),
|
return preparedStatementProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
PREPARED_STMNT_PROXY_INTERFACES,
|
}
|
||||||
proxyHandler
|
catch (Exception e) {
|
||||||
);
|
throw new JdbcProxyException( "Could not instantiate JDBC PreparedStatement proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,22 +207,45 @@ public class ProxyBuilder {
|
||||||
InvalidatableWrapper.class
|
InvalidatableWrapper.class
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final Value<Constructor<CallableStatement>> callableStatementProxyConstructorValue = new Value<Constructor<CallableStatement>>(
|
||||||
|
new Value.DeferredInitializer<Constructor<CallableStatement>>() {
|
||||||
|
@Override
|
||||||
|
public Constructor<CallableStatement> initialize() {
|
||||||
|
try {
|
||||||
|
return locateCallableStatementProxyClass().getConstructor( InvocationHandler.class );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Statement proxy class", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<CallableStatement> locateCallableStatementProxyClass() {
|
||||||
|
return (Class<CallableStatement>) Proxy.getProxyClass(
|
||||||
|
JdbcWrapper.class.getClassLoader(),
|
||||||
|
CALLABLE_STMNT_PROXY_INTERFACES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
public static CallableStatement buildCallableStatement(
|
public static CallableStatement buildCallableStatement(
|
||||||
String sql,
|
String sql,
|
||||||
CallableStatement statement,
|
CallableStatement statement,
|
||||||
ConnectionProxyHandler connectionProxyHandler,
|
ConnectionProxyHandler connectionProxyHandler,
|
||||||
Connection connectionProxy) {
|
Connection connectionProxy) {
|
||||||
CallableStatementProxyHandler proxyHandler = new CallableStatementProxyHandler(
|
final CallableStatementProxyHandler proxyHandler = new CallableStatementProxyHandler(
|
||||||
sql,
|
sql,
|
||||||
statement,
|
statement,
|
||||||
connectionProxyHandler,
|
connectionProxyHandler,
|
||||||
connectionProxy
|
connectionProxy
|
||||||
);
|
);
|
||||||
return ( CallableStatement ) Proxy.newProxyInstance(
|
try {
|
||||||
JdbcWrapper.class.getClassLoader(),
|
return callableStatementProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
CALLABLE_STMNT_PROXY_INTERFACES,
|
}
|
||||||
proxyHandler
|
catch (Exception e) {
|
||||||
);
|
throw new JdbcProxyException( "Could not instantiate JDBC CallableStatement proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,29 +257,56 @@ public class ProxyBuilder {
|
||||||
InvalidatableWrapper.class
|
InvalidatableWrapper.class
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final Value<Constructor<ResultSet>> resultSetProxyConstructorValue = new Value<Constructor<ResultSet>>(
|
||||||
|
new Value.DeferredInitializer<Constructor<ResultSet>>() {
|
||||||
|
@Override
|
||||||
|
public Constructor<ResultSet> initialize() {
|
||||||
|
try {
|
||||||
|
return locateCallableStatementProxyClass().getConstructor( InvocationHandler.class );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated ResultSet proxy class", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<ResultSet> locateCallableStatementProxyClass() {
|
||||||
|
return (Class<ResultSet>) Proxy.getProxyClass(
|
||||||
|
JdbcWrapper.class.getClassLoader(),
|
||||||
|
RESULTSET_PROXY_INTERFACES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
public static ResultSet buildResultSet(
|
public static ResultSet buildResultSet(
|
||||||
ResultSet resultSet,
|
ResultSet resultSet,
|
||||||
AbstractStatementProxyHandler statementProxyHandler,
|
AbstractStatementProxyHandler statementProxyHandler,
|
||||||
Statement statementProxy) {
|
Statement statementProxy) {
|
||||||
ResultSetProxyHandler proxyHandler = new ResultSetProxyHandler( resultSet, statementProxyHandler, statementProxy );
|
final ResultSetProxyHandler proxyHandler = new ResultSetProxyHandler( resultSet, statementProxyHandler, statementProxy );
|
||||||
return ( ResultSet ) Proxy.newProxyInstance(
|
try {
|
||||||
JdbcWrapper.class.getClassLoader(),
|
return resultSetProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
RESULTSET_PROXY_INTERFACES,
|
}
|
||||||
proxyHandler
|
catch (Exception e) {
|
||||||
);
|
throw new JdbcProxyException( "Could not instantiate JDBC ResultSet proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResultSet buildImplicitResultSet(
|
public static ResultSet buildImplicitResultSet(
|
||||||
ResultSet resultSet,
|
ResultSet resultSet,
|
||||||
ConnectionProxyHandler connectionProxyHandler,
|
ConnectionProxyHandler connectionProxyHandler,
|
||||||
Connection connectionProxy) {
|
Connection connectionProxy) {
|
||||||
ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler( resultSet, connectionProxyHandler, connectionProxy );
|
final ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler(
|
||||||
return ( ResultSet ) Proxy.newProxyInstance(
|
resultSet,
|
||||||
JdbcWrapper.class.getClassLoader(),
|
connectionProxyHandler,
|
||||||
RESULTSET_PROXY_INTERFACES,
|
connectionProxy
|
||||||
proxyHandler
|
|
||||||
);
|
);
|
||||||
|
try {
|
||||||
|
return resultSetProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new JdbcProxyException( "Could not instantiate JDBC ResultSet proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResultSet buildImplicitResultSet(
|
public static ResultSet buildImplicitResultSet(
|
||||||
|
@ -190,12 +314,18 @@ public class ProxyBuilder {
|
||||||
ConnectionProxyHandler connectionProxyHandler,
|
ConnectionProxyHandler connectionProxyHandler,
|
||||||
Connection connectionProxy,
|
Connection connectionProxy,
|
||||||
Statement sourceStatement) {
|
Statement sourceStatement) {
|
||||||
ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler( resultSet, connectionProxyHandler, connectionProxy, sourceStatement );
|
final ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler(
|
||||||
return ( ResultSet ) Proxy.newProxyInstance(
|
resultSet,
|
||||||
JdbcWrapper.class.getClassLoader(),
|
connectionProxyHandler,
|
||||||
RESULTSET_PROXY_INTERFACES,
|
connectionProxy,
|
||||||
proxyHandler
|
sourceStatement
|
||||||
);
|
);
|
||||||
|
try {
|
||||||
|
return resultSetProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new JdbcProxyException( "Could not instantiate JDBC ResultSet proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,15 +336,42 @@ public class ProxyBuilder {
|
||||||
JdbcWrapper.class
|
JdbcWrapper.class
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final Value<Constructor<DatabaseMetaData>> metadataProxyConstructorValue = new Value<Constructor<DatabaseMetaData>>(
|
||||||
|
new Value.DeferredInitializer<Constructor<DatabaseMetaData>>() {
|
||||||
|
@Override
|
||||||
|
public Constructor<DatabaseMetaData> initialize() {
|
||||||
|
try {
|
||||||
|
return locateDatabaseMetaDataProxyClass().getConstructor( InvocationHandler.class );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated DatabaseMetaData proxy class", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<DatabaseMetaData> locateDatabaseMetaDataProxyClass() {
|
||||||
|
return (Class<DatabaseMetaData>) Proxy.getProxyClass(
|
||||||
|
JdbcWrapper.class.getClassLoader(),
|
||||||
|
METADATA_PROXY_INTERFACES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
public static DatabaseMetaData buildDatabaseMetaData(
|
public static DatabaseMetaData buildDatabaseMetaData(
|
||||||
DatabaseMetaData metaData,
|
DatabaseMetaData metaData,
|
||||||
ConnectionProxyHandler connectionProxyHandler,
|
ConnectionProxyHandler connectionProxyHandler,
|
||||||
Connection connectionProxy) {
|
Connection connectionProxy) {
|
||||||
DatabaseMetaDataProxyHandler handler = new DatabaseMetaDataProxyHandler( metaData, connectionProxyHandler, connectionProxy );
|
final DatabaseMetaDataProxyHandler proxyHandler = new DatabaseMetaDataProxyHandler(
|
||||||
return ( DatabaseMetaData ) Proxy.newProxyInstance(
|
metaData,
|
||||||
JdbcWrapper.class.getClassLoader(),
|
connectionProxyHandler,
|
||||||
METADATA_PROXY_INTERFACES,
|
connectionProxy
|
||||||
handler
|
|
||||||
);
|
);
|
||||||
|
try {
|
||||||
|
return metadataProxyConstructorValue.getValue().newInstance( proxyHandler );
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new JdbcProxyException( "Could not instantiate JDBC DatabaseMetaData proxy", e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue