HHH-8118 wired ClassLoaderService into Lob proxies and LobCreator

This commit is contained in:
Brett Meyer 2013-08-06 16:39:00 -04:00 committed by Brett Meyer
parent 5143caf303
commit 0f453745dc
25 changed files with 163 additions and 168 deletions

View File

@ -26,15 +26,24 @@ import java.sql.Blob;
import java.sql.Clob; import java.sql.Clob;
import java.sql.NClob; import java.sql.NClob;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/** /**
* Convenient base class for proxy-based LobCreator for handling wrapping. * Convenient base class for proxy-based LobCreator for handling wrapping.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractLobCreator implements LobCreator { public abstract class AbstractLobCreator implements LobCreator {
private final ClassLoaderService classLoaderService;
public AbstractLobCreator(ClassLoaderService classLoaderService) {
this.classLoaderService = classLoaderService;
}
@Override @Override
public Blob wrap(Blob blob) { public Blob wrap(Blob blob) {
return SerializableBlobProxy.generateProxy( blob ); return SerializableBlobProxy.generateProxy( blob, classLoaderService );
} }
@Override @Override
@ -43,12 +52,12 @@ public abstract class AbstractLobCreator implements LobCreator {
return wrap( (NClob) clob ); return wrap( (NClob) clob );
} }
else { else {
return SerializableClobProxy.generateProxy( clob ); return SerializableClobProxy.generateProxy( clob, classLoaderService );
} }
} }
@Override @Override
public NClob wrap(NClob nclob) { public NClob wrap(NClob nclob) {
return SerializableNClobProxy.generateProxy( nclob ); return SerializableNClobProxy.generateProxy( nclob, classLoaderService );
} }
} }

View File

@ -31,8 +31,8 @@ import java.lang.reflect.Proxy;
import java.sql.Blob; import java.sql.Blob;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl; import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.hibernate.internal.util.ClassLoaderHelper;
import org.hibernate.type.descriptor.java.DataHelper; import org.hibernate.type.descriptor.java.DataHelper;
/** /**
@ -169,11 +169,13 @@ public class BlobProxy implements InvocationHandler {
* Generates a BlobImpl proxy using byte data. * Generates a BlobImpl proxy using byte data.
* *
* @param bytes The data to be created as a Blob. * @param bytes The data to be created as a Blob.
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Blob generateProxy(byte[] bytes) { public static Blob generateProxy(byte[] bytes, ClassLoaderService classLoaderService) {
return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new BlobProxy( bytes ) ); return (Blob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(),
PROXY_INTERFACES, new BlobProxy( bytes ) );
} }
/** /**
@ -181,25 +183,13 @@ public class BlobProxy implements InvocationHandler {
* *
* @param stream The input stream of bytes to be created as a Blob. * @param stream The input stream of bytes to be created as a Blob.
* @param length The number of bytes from stream to be written to the Blob. * @param length The number of bytes from stream to be written to the Blob.
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Blob generateProxy(InputStream stream, long length) { public static Blob generateProxy(InputStream stream, long length, ClassLoaderService classLoaderService) {
return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new BlobProxy( stream, length ) ); return (Blob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(),
} PROXY_INTERFACES, new BlobProxy( stream, length ) );
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
private static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = BlobImplementer.class.getClassLoader();
}
return cl;
} }
private static class StreamBackedBinaryStream implements BinaryStream { private static class StreamBackedBinaryStream implements BinaryStream {

View File

@ -32,8 +32,8 @@ import java.lang.reflect.Proxy;
import java.sql.Clob; import java.sql.Clob;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl; import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
import org.hibernate.internal.util.ClassLoaderHelper;
import org.hibernate.type.descriptor.java.DataHelper; import org.hibernate.type.descriptor.java.DataHelper;
/** /**
@ -185,11 +185,13 @@ public class ClobProxy implements InvocationHandler {
* Generates a {@link Clob} proxy using the string data. * Generates a {@link Clob} proxy using the string data.
* *
* @param string The data to be wrapped as a {@link Clob}. * @param string The data to be wrapped as a {@link Clob}.
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Clob generateProxy(String string) { public static Clob generateProxy(String string, ClassLoaderService classLoaderService) {
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( string ) ); return (Clob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
new ClobProxy( string ) );
} }
/** /**
@ -197,24 +199,12 @@ public class ClobProxy implements InvocationHandler {
* *
* @param reader The character reader * @param reader The character reader
* @param length The length of the character reader * @param length The length of the character reader
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Clob generateProxy(Reader reader, long length) { public static Clob generateProxy(Reader reader, long length, ClassLoaderService classLoaderService) {
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( reader, length ) ); return (Clob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
} new ClobProxy( reader, length ) );
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
protected static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = ClobImplementer.class.getClassLoader();
}
return cl;
} }
} }

View File

@ -39,9 +39,11 @@ import org.hibernate.JDBCException;
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner * @author Gail Badner
* @author Brett Meyer
*/ */
public class ContextualLobCreator extends AbstractLobCreator implements LobCreator { public class ContextualLobCreator extends AbstractLobCreator implements LobCreator {
private LobCreationContext lobCreationContext; private final LobCreationContext lobCreationContext;
private final NonContextualLobCreator nonContextCreator;
/** /**
* Constructs a ContextualLobCreator * Constructs a ContextualLobCreator
@ -49,7 +51,9 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
* @param lobCreationContext The context for performing LOB creation * @param lobCreationContext The context for performing LOB creation
*/ */
public ContextualLobCreator(LobCreationContext lobCreationContext) { public ContextualLobCreator(LobCreationContext lobCreationContext) {
super( lobCreationContext.classLoaderService() );
this.lobCreationContext = lobCreationContext; this.lobCreationContext = lobCreationContext;
nonContextCreator = new NonContextualLobCreator( lobCreationContext.classLoaderService() );
} }
/** /**
@ -77,7 +81,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
public Blob createBlob(InputStream inputStream, long length) { public Blob createBlob(InputStream inputStream, long length) {
// IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB // IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB
// backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does). // backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does).
return NonContextualLobCreator.INSTANCE.createBlob( inputStream, length ); return nonContextCreator.createBlob( inputStream, length );
} }
/** /**
@ -105,7 +109,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
public Clob createClob(Reader reader, long length) { public Clob createClob(Reader reader, long length) {
// IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB // IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB
// backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does). // backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does).
return NonContextualLobCreator.INSTANCE.createClob( reader, length ); return nonContextCreator.createClob( reader, length );
} }
/** /**
@ -133,7 +137,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
public NClob createNClob(Reader reader, long length) { public NClob createNClob(Reader reader, long length) {
// IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB // IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB
// backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does). // backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does).
return NonContextualLobCreator.INSTANCE.createNClob( reader, length ); return nonContextCreator.createNClob( reader, length );
} }
/** /**

View File

@ -25,10 +25,13 @@ package org.hibernate.engine.jdbc;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/** /**
* Provides callback access into the context in which the LOB is to be created. * Provides callback access into the context in which the LOB is to be created.
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Brett Meyer
*/ */
public interface LobCreationContext { public interface LobCreationContext {
/** /**
@ -57,4 +60,11 @@ public interface LobCreationContext {
* @return The LOB created by the callback. * @return The LOB created by the callback.
*/ */
public <T> T execute(Callback<T> callback); public <T> T execute(Callback<T> callback);
/**
* The lob proxies need a ClassLoader for use during creation.
*
* @return ClassLoaderService
*/
public ClassLoaderService classLoaderService();
} }

View File

@ -27,6 +27,7 @@ import java.io.Reader;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.sql.NClob; import java.sql.NClob;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.internal.util.ClassLoaderHelper; import org.hibernate.internal.util.ClassLoaderHelper;
/** /**
@ -56,11 +57,13 @@ public class NClobProxy extends ClobProxy {
* Generates a {@link java.sql.Clob} proxy using the string data. * Generates a {@link java.sql.Clob} proxy using the string data.
* *
* @param string The data to be wrapped as a {@link java.sql.Clob}. * @param string The data to be wrapped as a {@link java.sql.Clob}.
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static NClob generateProxy(String string) { public static NClob generateProxy(String string, ClassLoaderService classLoaderService) {
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( string ) ); return (NClob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
new ClobProxy( string ) );
} }
/** /**
@ -68,24 +71,12 @@ public class NClobProxy extends ClobProxy {
* *
* @param reader The character reader * @param reader The character reader
* @param length The length of the character reader * @param length The length of the character reader
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static NClob generateProxy(Reader reader, long length) { public static NClob generateProxy(Reader reader, long length, ClassLoaderService classLoaderService) {
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( reader, length ) ); return (NClob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
} new ClobProxy( reader, length ) );
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
protected static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = NClobImplementer.class.getClassLoader();
}
return cl;
} }
} }

View File

@ -29,6 +29,8 @@ import java.sql.Blob;
import java.sql.Clob; import java.sql.Clob;
import java.sql.NClob; import java.sql.NClob;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/** /**
* {@link LobCreator} implementation using non-contextual or local creation, meaning that we generate the LOB * {@link LobCreator} implementation using non-contextual or local creation, meaning that we generate the LOB
* references ourselves as opposed to delegating to the JDBC {@link java.sql.Connection}. * references ourselves as opposed to delegating to the JDBC {@link java.sql.Connection}.
@ -37,41 +39,41 @@ import java.sql.NClob;
* @author Gail Badner * @author Gail Badner
*/ */
public class NonContextualLobCreator extends AbstractLobCreator implements LobCreator { public class NonContextualLobCreator extends AbstractLobCreator implements LobCreator {
/**
* Singleton access
*/
public static final NonContextualLobCreator INSTANCE = new NonContextualLobCreator();
private NonContextualLobCreator() { private final ClassLoaderService classLoaderService;
public NonContextualLobCreator(ClassLoaderService classLoaderService) {
super( classLoaderService );
this.classLoaderService = classLoaderService;
} }
@Override @Override
public Blob createBlob(byte[] bytes) { public Blob createBlob(byte[] bytes) {
return BlobProxy.generateProxy( bytes ); return BlobProxy.generateProxy( bytes, classLoaderService );
} }
@Override @Override
public Blob createBlob(InputStream stream, long length) { public Blob createBlob(InputStream stream, long length) {
return BlobProxy.generateProxy( stream, length ); return BlobProxy.generateProxy( stream, length, classLoaderService );
} }
@Override @Override
public Clob createClob(String string) { public Clob createClob(String string) {
return ClobProxy.generateProxy( string ); return ClobProxy.generateProxy( string, classLoaderService );
} }
@Override @Override
public Clob createClob(Reader reader, long length) { public Clob createClob(Reader reader, long length) {
return ClobProxy.generateProxy( reader, length ); return ClobProxy.generateProxy( reader, length, classLoaderService );
} }
@Override @Override
public NClob createNClob(String string) { public NClob createNClob(String string) {
return NClobProxy.generateProxy( string ); return NClobProxy.generateProxy( string, classLoaderService );
} }
@Override @Override
public NClob createNClob(Reader reader, long length) { public NClob createNClob(Reader reader, long length) {
return NClobProxy.generateProxy( reader, length ); return NClobProxy.generateProxy( reader, length, classLoaderService );
} }
} }

View File

@ -30,11 +30,10 @@ import java.lang.reflect.Proxy;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.jboss.logging.Logger; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ClassLoaderHelper; import org.jboss.logging.Logger;
/** /**
* A proxy for a ResultSet delegate, responsible for locally caching the columnName-to-columnIndex resolution that * A proxy for a ResultSet delegate, responsible for locally caching the columnName-to-columnIndex resolution that
@ -64,30 +63,18 @@ public class ResultSetWrapperProxy implements InvocationHandler {
* *
* @param resultSet The resultSet to wrap. * @param resultSet The resultSet to wrap.
* @param columnNameCache The cache storing data for converting column names to column indexes. * @param columnNameCache The cache storing data for converting column names to column indexes.
* @param classLoaderService
* @return The generated proxy. * @return The generated proxy.
*/ */
public static ResultSet generateProxy(ResultSet resultSet, ColumnNameCache columnNameCache) { public static ResultSet generateProxy(ResultSet resultSet, ColumnNameCache columnNameCache,
ClassLoaderService classLoaderService) {
return (ResultSet) Proxy.newProxyInstance( return (ResultSet) Proxy.newProxyInstance(
getProxyClassLoader(), classLoaderService.getAggregatedClassLoader(),
PROXY_INTERFACES, PROXY_INTERFACES,
new ResultSetWrapperProxy( resultSet, columnNameCache ) new ResultSetWrapperProxy( resultSet, columnNameCache )
); );
} }
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = ResultSet.class.getClassLoader();
}
return cl;
}
@Override @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ( "findColumn".equals( method.getName() ) ) { if ( "findColumn".equals( method.getName() ) ) {

View File

@ -31,7 +31,7 @@ import java.lang.reflect.Proxy;
import java.sql.Blob; import java.sql.Blob;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.internal.util.ClassLoaderHelper; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/** /**
* Manages aspects of proxying {@link Blob Blobs} to add serializability. * Manages aspects of proxying {@link Blob Blobs} to add serializability.
@ -89,24 +89,12 @@ public class SerializableBlobProxy implements InvocationHandler, Serializable {
* Generates a SerializableBlob proxy wrapping the provided Blob object. * Generates a SerializableBlob proxy wrapping the provided Blob object.
* *
* @param blob The Blob to wrap. * @param blob The Blob to wrap.
* @param classLoaderService
* *
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Blob generateProxy(Blob blob) { public static Blob generateProxy(Blob blob, ClassLoaderService classLoaderService) {
return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableBlobProxy( blob ) ); return (Blob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
} new SerializableBlobProxy( blob ) );
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = WrappedBlob.class.getClassLoader();
}
return cl;
} }
} }

View File

@ -31,7 +31,7 @@ import java.lang.reflect.Proxy;
import java.sql.Clob; import java.sql.Clob;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.internal.util.ClassLoaderHelper; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/** /**
* Manages aspects of proxying {@link Clob Clobs} to add serializability. * Manages aspects of proxying {@link Clob Clobs} to add serializability.
@ -89,23 +89,11 @@ public class SerializableClobProxy implements InvocationHandler, Serializable {
* Generates a SerializableClobProxy proxy wrapping the provided Clob object. * Generates a SerializableClobProxy proxy wrapping the provided Clob object.
* *
* @param clob The Clob to wrap. * @param clob The Clob to wrap.
* @param classLoaderService
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Clob generateProxy(Clob clob) { public static Clob generateProxy(Clob clob, ClassLoaderService classLoaderService) {
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableClobProxy( clob ) ); return (Clob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
} new SerializableClobProxy( clob ) );
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = WrappedClob.class.getClassLoader();
}
return cl;
} }
} }

View File

@ -27,6 +27,8 @@ import java.lang.reflect.Proxy;
import java.sql.Clob; import java.sql.Clob;
import java.sql.NClob; import java.sql.NClob;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/** /**
* Manages aspects of proxying java.sql.NClobs to add serializability. * Manages aspects of proxying java.sql.NClobs to add serializability.
* *
@ -64,19 +66,11 @@ public class SerializableNClobProxy extends SerializableClobProxy {
* Generates a SerializableNClobProxy proxy wrapping the provided NClob object. * Generates a SerializableNClobProxy proxy wrapping the provided NClob object.
* *
* @param nclob The NClob to wrap. * @param nclob The NClob to wrap.
* @param classLoaderService
* @return The generated proxy. * @return The generated proxy.
*/ */
public static NClob generateProxy(NClob nclob) { public static NClob generateProxy(NClob nclob, ClassLoaderService classLoaderService) {
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableNClobProxy( nclob ) ); return (NClob) Proxy.newProxyInstance( classLoaderService.getAggregatedClassLoader(), PROXY_INTERFACES,
} new SerializableNClobProxy( nclob ) );
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
return SerializableClobProxy.getProxyClassLoader();
} }
} }

View File

@ -58,7 +58,7 @@ public class LobCreatorBuilderImpl implements LobCreatorBuilder {
public LobCreator buildLobCreator(LobCreationContext lobCreationContext) { public LobCreator buildLobCreator(LobCreationContext lobCreationContext) {
return useContextualLobCreation return useContextualLobCreation
? new ContextualLobCreator( lobCreationContext ) ? new ContextualLobCreator( lobCreationContext )
: NonContextualLobCreator.INSTANCE; : new NonContextualLobCreator( lobCreationContext.classLoaderService() );
} }

View File

@ -25,6 +25,7 @@ package org.hibernate.engine.jdbc.internal;
import java.sql.ResultSet; import java.sql.ResultSet;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.jdbc.ColumnNameCache; import org.hibernate.engine.jdbc.ColumnNameCache;
import org.hibernate.engine.jdbc.ResultSetWrapperProxy; import org.hibernate.engine.jdbc.ResultSetWrapperProxy;
import org.hibernate.engine.jdbc.spi.ResultSetWrapper; import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
@ -46,7 +47,7 @@ public class ResultSetWrapperImpl implements ResultSetWrapper {
} }
@Override @Override
public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache) { public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache, ClassLoaderService classLoaderService) {
return ResultSetWrapperProxy.generateProxy( resultSet, columnNameCache ); return ResultSetWrapperProxy.generateProxy( resultSet, columnNameCache, classLoaderService );
} }
} }

View File

@ -25,6 +25,7 @@ package org.hibernate.engine.jdbc.spi;
import java.sql.ResultSet; import java.sql.ResultSet;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.jdbc.ColumnNameCache; import org.hibernate.engine.jdbc.ColumnNameCache;
/** /**
@ -38,8 +39,9 @@ public interface ResultSetWrapper {
* *
* @param resultSet The result set to wrap * @param resultSet The result set to wrap
* @param columnNameCache The column name cache. * @param columnNameCache The column name cache.
* @param classLoaderService
* *
* @return The wrapped result set. * @return The wrapped result set.
*/ */
public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache); public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache, ClassLoaderService classLoaderService);
} }

View File

@ -52,6 +52,7 @@ import org.hibernate.SimpleNaturalIdLoadAccess;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.hibernate.TypeHelper; import org.hibernate.TypeHelper;
import org.hibernate.UnknownProfileException; import org.hibernate.UnknownProfileException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.CacheKey;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
@ -790,4 +791,9 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
return session.getLobHelper(); return session.getLobHelper();
} }
@Override
public ClassLoaderService classLoaderService() {
return getFactory().getServiceRegistry().getService( ClassLoaderService.class );
}
} }

View File

@ -37,6 +37,7 @@ import org.hibernate.SQLQuery;
import org.hibernate.ScrollableResults; import org.hibernate.ScrollableResults;
import org.hibernate.SessionException; import org.hibernate.SessionException;
import org.hibernate.SharedSessionContract; import org.hibernate.SharedSessionContract;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.CacheKey;
import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
@ -317,6 +318,11 @@ public abstract class AbstractSessionImpl
return new CacheKey( id, type, entityOrRoleName, getTenantIdentifier(), getFactory() ); return new CacheKey( id, type, entityOrRoleName, getTenantIdentifier(), getFactory() );
} }
@Override
public ClassLoaderService classLoaderService() {
return getFactory().getServiceRegistry().getService( ClassLoaderService.class );
}
private transient JdbcConnectionAccess jdbcConnectionAccess; private transient JdbcConnectionAccess jdbcConnectionAccess;
@Override @Override

View File

@ -44,9 +44,8 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.EntityNotFoundException;
import org.jboss.logging.Logger; import javax.persistence.EntityNotFoundException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
@ -158,6 +157,7 @@ import org.hibernate.stat.SessionStatistics;
import org.hibernate.stat.internal.SessionStatisticsImpl; import org.hibernate.stat.internal.SessionStatisticsImpl;
import org.hibernate.type.SerializationException; import org.hibernate.type.SerializationException;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.jboss.logging.Logger;
/** /**
* Concrete implementation of a Session. * Concrete implementation of a Session.
@ -2247,7 +2247,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
private LobCreator lobCreator() { private LobCreator lobCreator() {
// Always use NonContextualLobCreator. If ContextualLobCreator is // Always use NonContextualLobCreator. If ContextualLobCreator is
// used both here and in WrapperOptions, // used both here and in WrapperOptions,
return NonContextualLobCreator.INSTANCE; return new NonContextualLobCreator(session.classLoaderService());
} }
@Override @Override

View File

@ -2070,7 +2070,8 @@ public abstract class Loader {
LOG.debugf( "Wrapping result set [%s]", rs ); LOG.debugf( "Wrapping result set [%s]", rs );
return session.getFactory() return session.getFactory()
.getJdbcServices() .getJdbcServices()
.getResultSetWrapper().wrap( rs, retreiveColumnNameToIndexCache( rs ) ); .getResultSetWrapper().wrap( rs, retreiveColumnNameToIndexCache( rs ),
session.classLoaderService());
} }
catch(SQLException e) { catch(SQLException e) {
LOG.unableToWrapResultSet( e ); LOG.unableToWrapResultSet( e );

View File

@ -31,6 +31,7 @@ import java.sql.SQLException;
import java.util.Comparator; import java.util.Comparator;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.BlobImplementer; import org.hibernate.engine.jdbc.BlobImplementer;
import org.hibernate.engine.jdbc.BlobProxy; import org.hibernate.engine.jdbc.BlobProxy;
@ -92,7 +93,9 @@ public class BlobTypeDescriptor extends AbstractTypeDescriptor<Blob> {
* {@inheritDoc} * {@inheritDoc}
*/ */
public Blob fromString(String string) { public Blob fromString(String string) {
return BlobProxy.generateProxy( PrimitiveByteArrayTypeDescriptor.INSTANCE.fromString( string ) ); // TODO: Temporary fix. Need to thing through how to wire CLS up properly.
return BlobProxy.generateProxy( PrimitiveByteArrayTypeDescriptor.INSTANCE.fromString( string ),
new ClassLoaderServiceImpl() );
} }
@Override @Override

View File

@ -30,6 +30,7 @@ import java.sql.SQLException;
import java.util.Comparator; import java.util.Comparator;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.engine.jdbc.CharacterStream; import org.hibernate.engine.jdbc.CharacterStream;
import org.hibernate.engine.jdbc.ClobImplementer; import org.hibernate.engine.jdbc.ClobImplementer;
import org.hibernate.engine.jdbc.ClobProxy; import org.hibernate.engine.jdbc.ClobProxy;
@ -77,7 +78,8 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor<Clob> {
} }
public Clob fromString(String string) { public Clob fromString(String string) {
return ClobProxy.generateProxy( string ); // TODO: Temporary fix. Need to thing through how to wire CLS up properly.
return ClobProxy.generateProxy( string, new ClassLoaderServiceImpl() );
} }
@Override @Override

View File

@ -30,6 +30,7 @@ import java.sql.SQLException;
import java.util.Comparator; import java.util.Comparator;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.engine.jdbc.CharacterStream; import org.hibernate.engine.jdbc.CharacterStream;
import org.hibernate.engine.jdbc.NClobImplementer; import org.hibernate.engine.jdbc.NClobImplementer;
import org.hibernate.engine.jdbc.NClobProxy; import org.hibernate.engine.jdbc.NClobProxy;
@ -77,7 +78,8 @@ public class NClobTypeDescriptor extends AbstractTypeDescriptor<NClob> {
} }
public NClob fromString(String string) { public NClob fromString(String string) {
return NClobProxy.generateProxy( string ); // TODO: Temporary fix. Need to thing through how to wire CLS up properly.
return NClobProxy.generateProxy( string, new ClassLoaderServiceImpl() );
} }
@Override @Override

View File

@ -23,6 +23,8 @@
*/ */
package org.hibernate.jdbc; package org.hibernate.jdbc;
import static org.junit.Assert.assertTrue;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Reader; import java.io.Reader;
@ -38,8 +40,8 @@ import java.sql.NClob;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Properties; import java.util.Properties;
import org.junit.Test; import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.BlobImplementer; import org.hibernate.engine.jdbc.BlobImplementer;
import org.hibernate.engine.jdbc.ClobImplementer; import org.hibernate.engine.jdbc.ClobImplementer;
@ -51,9 +53,7 @@ import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.WrappedBlob; import org.hibernate.engine.jdbc.WrappedBlob;
import org.hibernate.engine.jdbc.WrappedClob; import org.hibernate.engine.jdbc.WrappedClob;
import org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl; import org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl;
import org.junit.Test;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -79,7 +79,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection ) LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection )
.buildLobCreator( lobCreationContext ); .buildLobCreator( lobCreationContext );
assertSame( NonContextualLobCreator.INSTANCE, lobCreator ); assertTrue( lobCreator instanceof NonContextualLobCreator );
testLobCreation( lobCreator ); testLobCreation( lobCreator );
connection.close(); connection.close();
@ -91,7 +91,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection ) LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection )
.buildLobCreator( lobCreationContext ); .buildLobCreator( lobCreationContext );
assertSame( NonContextualLobCreator.INSTANCE, lobCreator ); assertTrue( lobCreator instanceof NonContextualLobCreator );
testLobCreation( lobCreator ); testLobCreation( lobCreator );
connection.close(); connection.close();
@ -105,7 +105,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
props.setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" ); props.setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" );
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( props, connection ) LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( props, connection )
.buildLobCreator( lobCreationContext ); .buildLobCreator( lobCreationContext );
assertSame( NonContextualLobCreator.INSTANCE, lobCreator ); assertTrue( lobCreator instanceof NonContextualLobCreator );
testLobCreation( lobCreator ); testLobCreation( lobCreator );
connection.close(); connection.close();
@ -113,7 +113,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
private void testLobCreation(LobCreator lobCreator) throws SQLException{ private void testLobCreation(LobCreator lobCreator) throws SQLException{
Blob blob = lobCreator.createBlob( new byte[] {} ); Blob blob = lobCreator.createBlob( new byte[] {} );
if ( lobCreator == NonContextualLobCreator.INSTANCE ) { if ( lobCreator instanceof NonContextualLobCreator ) {
assertTrue( blob instanceof BlobImplementer ); assertTrue( blob instanceof BlobImplementer );
} }
else { else {
@ -123,7 +123,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
assertTrue( blob instanceof WrappedBlob ); assertTrue( blob instanceof WrappedBlob );
Clob clob = lobCreator.createClob( "Hi" ); Clob clob = lobCreator.createClob( "Hi" );
if ( lobCreator == NonContextualLobCreator.INSTANCE ) { if ( lobCreator instanceof NonContextualLobCreator ) {
assertTrue( clob instanceof ClobImplementer ); assertTrue( clob instanceof ClobImplementer );
} }
else { else {
@ -133,7 +133,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
assertTrue( clob instanceof WrappedClob ); assertTrue( clob instanceof WrappedClob );
Clob nclob = lobCreator.createNClob( "Hi" ); Clob nclob = lobCreator.createNClob( "Hi" );
if ( lobCreator == NonContextualLobCreator.INSTANCE ) { if ( lobCreator instanceof NonContextualLobCreator ) {
assertTrue( nclob instanceof NClobImplementer ); assertTrue( nclob instanceof NClobImplementer );
} }
else { else {
@ -149,7 +149,8 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
} }
private class LobCreationContextImpl implements LobCreationContext { private class LobCreationContextImpl implements LobCreationContext {
private Connection connection; private final ClassLoaderService classLoaderService = new ClassLoaderServiceImpl();
private final Connection connection;
private LobCreationContextImpl(Connection connection) { private LobCreationContextImpl(Connection connection) {
this.connection = connection; this.connection = connection;
@ -163,6 +164,11 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
throw new RuntimeException( "Unexpected SQLException", e ); throw new RuntimeException( "Unexpected SQLException", e );
} }
} }
@Override
public ClassLoaderService classLoaderService() {
return classLoaderService;
}
} }
private interface JdbcLobBuilder { private interface JdbcLobBuilder {

View File

@ -32,6 +32,8 @@ import java.io.IOException;
import java.sql.Blob; import java.sql.Blob;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.jdbc.BlobImplementer; import org.hibernate.engine.jdbc.BlobImplementer;
import org.hibernate.engine.jdbc.BlobProxy; import org.hibernate.engine.jdbc.BlobProxy;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
@ -44,9 +46,10 @@ import org.junit.Test;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class BlobDescriptorTest extends AbstractDescriptorTest<Blob> { public class BlobDescriptorTest extends AbstractDescriptorTest<Blob> {
final Blob original = BlobProxy.generateProxy( new byte[] { 1, 2, 3 } ); private final ClassLoaderService classLoaderService = new ClassLoaderServiceImpl();
final Blob copy = BlobProxy.generateProxy( new byte[] { 1, 2, 3 } ); final Blob original = BlobProxy.generateProxy( new byte[] { 1, 2, 3 }, classLoaderService );
final Blob different = BlobProxy.generateProxy( new byte[] { 3, 2, 1 } ); final Blob copy = BlobProxy.generateProxy( new byte[] { 1, 2, 3 }, classLoaderService );
final Blob different = BlobProxy.generateProxy( new byte[] { 3, 2, 1 }, classLoaderService );
public BlobDescriptorTest() { public BlobDescriptorTest() {
super( BlobTypeDescriptor.INSTANCE ); super( BlobTypeDescriptor.INSTANCE );
@ -93,7 +96,7 @@ public class BlobDescriptorTest extends AbstractDescriptorTest<Blob> {
@TestForIssue( jiraKey = "HHH-8193" ) @TestForIssue( jiraKey = "HHH-8193" )
public void testStreamResetOnAccess() throws IOException { public void testStreamResetOnAccess() throws IOException {
byte[] bytes = new byte[] { 1, 2, 3, 4 }; byte[] bytes = new byte[] { 1, 2, 3, 4 };
BlobImplementer blob = (BlobImplementer) BlobProxy.generateProxy( bytes ); BlobImplementer blob = (BlobImplementer) BlobProxy.generateProxy( bytes, classLoaderService );
int value = blob.getUnderlyingStream().getInputStream().read(); int value = blob.getUnderlyingStream().getInputStream().read();
// Call to BlobImplementer#getUnderlyingStream() should mark input stream for reset. // Call to BlobImplementer#getUnderlyingStream() should mark input stream for reset.
assertEquals( bytes.length, blob.getUnderlyingStream().getInputStream().available() ); assertEquals( bytes.length, blob.getUnderlyingStream().getInputStream().available() );

View File

@ -29,6 +29,7 @@ import java.sql.SQLException;
import org.junit.Test; import org.junit.Test;
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator; import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.testing.junit4.BaseUnitTestCase; import org.hibernate.testing.junit4.BaseUnitTestCase;
@ -53,12 +54,15 @@ public class StringValueMappingTest extends BaseUnitTestCase {
private final ClobTypeDescriptor clobSqlDescriptor = ClobTypeDescriptor.DEFAULT; private final ClobTypeDescriptor clobSqlDescriptor = ClobTypeDescriptor.DEFAULT;
private final WrapperOptions wrapperOptions = new WrapperOptions() { private final WrapperOptions wrapperOptions = new WrapperOptions() {
private final NonContextualLobCreator creator = new NonContextualLobCreator(
new ClassLoaderServiceImpl() );
public boolean useStreamForLobBinding() { public boolean useStreamForLobBinding() {
return false; return false;
} }
public LobCreator getLobCreator() { public LobCreator getLobCreator() {
return NonContextualLobCreator.INSTANCE; return creator;
} }
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) { public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {

View File

@ -37,6 +37,7 @@ import org.hibernate.Interceptor;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.ScrollMode; import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults; import org.hibernate.ScrollableResults;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.CacheKey;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
@ -359,4 +360,9 @@ public abstract class AbstractDelegateSessionImplementor implements SessionImple
public boolean isClosed() { public boolean isClosed() {
return delegate.isClosed(); return delegate.isClosed();
} }
@Override
public ClassLoaderService classLoaderService() {
return getFactory().getServiceRegistry().getService( ClassLoaderService.class );
}
} }