[hibernate-commits] Hibernate SVN: r17767 - in core/trunk: annotations/src/main/java/org/hibernate/type and 29 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Oct 15 12:26:28 EDT 2009


Author: steve.ebersole at jboss.com
Date: 2009-10-15 12:26:26 -0400 (Thu, 15 Oct 2009)
New Revision: 17767

Added:
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
   core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
   core/trunk/jdbc3-testing/
   core/trunk/jdbc3-testing/pom.xml
   core/trunk/jdbc3-testing/src/
   core/trunk/jdbc3-testing/src/test/
   core/trunk/jdbc3-testing/src/test/java/
   core/trunk/jdbc3-testing/src/test/java/org/
   core/trunk/jdbc3-testing/src/test/java/org/hibernate/
   core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/
   core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/
   core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/
   core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
   core/trunk/jdbc3-testing/src/test/resources/
   core/trunk/jdbc3-testing/src/test/resources/log4j.properties
   core/trunk/jdbc4-testing/
   core/trunk/jdbc4-testing/pom.xml
   core/trunk/jdbc4-testing/src/
   core/trunk/jdbc4-testing/src/test/
   core/trunk/jdbc4-testing/src/test/java/
   core/trunk/jdbc4-testing/src/test/java/org/
   core/trunk/jdbc4-testing/src/test/java/org/hibernate/
   core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/
   core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/
   core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/
   core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
   core/trunk/jdbc4-testing/src/test/resources/
   core/trunk/jdbc4-testing/src/test/resources/log4j.properties
Removed:
   core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
   core/trunk/core/src/main/java/org/hibernate/lob/
Modified:
   core/trunk/annotations/src/main/java/org/hibernate/type/ByteArrayBlobType.java
   core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java
   core/trunk/core/src/main/java/org/hibernate/Hibernate.java
   core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java
   core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
   core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
   core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
   core/trunk/core/src/main/java/org/hibernate/type/BlobType.java
   core/trunk/core/src/main/java/org/hibernate/type/ClobType.java
   core/trunk/parent/pom.xml
   core/trunk/pom.xml
Log:
HHH-2412 - Support for JDBC4


Modified: core/trunk/annotations/src/main/java/org/hibernate/type/ByteArrayBlobType.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/type/ByteArrayBlobType.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/annotations/src/main/java/org/hibernate/type/ByteArrayBlobType.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -34,11 +34,10 @@
 import org.dom4j.Node;
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
 import org.hibernate.engine.Mapping;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
 import org.hibernate.util.ArrayHelper;
 
 /**
@@ -51,9 +50,10 @@
  */
 @Deprecated
 public class ByteArrayBlobType extends AbstractLobType {
+	private static final int[] TYPES = new int[] { Types.BLOB };
 
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return new int[]{Types.BLOB};
+	public int[] sqlTypes(Mapping mapping) {
+		return TYPES;
 	}
 
 	@Override
@@ -128,7 +128,7 @@
 				st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
 			}
 			else {
-				st.setBlob( index, new BlobImpl( toSet ) );
+				st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
 			}
 		}
 	}

Modified: core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -37,10 +37,10 @@
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
 import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
 import org.hibernate.engine.Mapping;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
 import org.hibernate.usertype.ParameterizedType;
 import org.hibernate.util.ReflectHelper;
 import org.hibernate.util.SerializationHelper;
@@ -99,7 +99,7 @@
 				st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
 			}
 			else {
-				st.setBlob( index, new BlobImpl( toSet ) );
+				st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
 			}
 		}
 		else {

Modified: core/trunk/core/src/main/java/org/hibernate/Hibernate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Hibernate.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/Hibernate.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -28,6 +28,7 @@
 import java.io.InputStream;
 import java.io.Reader;
 import java.io.Serializable;
+import java.io.ByteArrayOutputStream;
 import java.sql.Blob;
 import java.sql.Clob;
 import java.util.Iterator;
@@ -35,12 +36,13 @@
 
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.engine.HibernateIterator;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.StreamUtils;
 import org.hibernate.intercept.FieldInterceptionHelper;
 import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.lob.BlobImpl;
-import org.hibernate.lob.ClobImpl;
-import org.hibernate.lob.SerializableBlob;
-import org.hibernate.lob.SerializableClob;
 import org.hibernate.proxy.HibernateProxy;
 import org.hibernate.proxy.LazyInitializer;
 import org.hibernate.type.AnyType;
@@ -386,57 +388,166 @@
 	}
 
 	/**
-	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+	 * Create a new {@link Blob}. The returned object will be initially immutable.
 	 *
 	 * @param bytes a byte array
 	 * @return the Blob
+	 * @deprecated Use {@link #createBlob(byte[], Session)} instead
 	 */
 	public static Blob createBlob(byte[] bytes) {
-		return new SerializableBlob( new BlobImpl( bytes ) );
+		return NonContextualLobCreator.INSTANCE.wrap(
+				NonContextualLobCreator.INSTANCE.createBlob( bytes )
+		);
 	}
 
 	/**
-	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+	 * Create a new {@link Blob}.
 	 *
+	 * @param bytes a byte array
+	 * @param session The session in which the {@link Blob} will be used.
+	 * @return the Blob
+	 */
+	public static Blob createBlob(byte[] bytes, Session session) {
+		// todo : wrap?
+		return getLobCreator( session ).createBlob( bytes );
+	}
+
+	public static LobCreator getLobCreator(Session session) {
+		return getLobCreator( ( SessionImplementor ) session );
+	}
+
+	public static LobCreator getLobCreator(SessionImplementor session) {
+		return session.getFactory()
+				.getSettings()
+				.getJdbcSupport()
+				.getLobCreator( ( LobCreationContext ) session );
+	}
+
+	/**
+	 * Create a new {@link Blob}. The returned object will be initially immutable.
+	 *
 	 * @param stream a binary stream
 	 * @param length the number of bytes in the stream
 	 * @return the Blob
+	 * @deprecated Use {@link #createBlob(InputStream, long, Session)} instead
 	 */
 	public static Blob createBlob(InputStream stream, int length) {
-		return new SerializableBlob( new BlobImpl( stream, length ) );
+		return NonContextualLobCreator.INSTANCE.wrap(
+				NonContextualLobCreator.INSTANCE.createBlob( stream, length )
+		);
 	}
 
 	/**
-	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+	 * Create a new {@link Blob}. The returned object will be initially immutable.
 	 *
 	 * @param stream a binary stream
+	 * @param length the number of bytes in the stream
 	 * @return the Blob
-	 * @throws IOException
+	 * @deprecated Use {@link #createBlob(InputStream, long, Session)} instead
 	 */
+	public static Blob createBlob(InputStream stream, long length) {
+		return NonContextualLobCreator.INSTANCE.wrap(
+				NonContextualLobCreator.INSTANCE.createBlob( stream, length )
+		);
+	}
+
+	/**
+	 * Create a new {@link Blob}.
+	 *
+	 * @param stream a binary stream
+	 * @param length the number of bytes in the stream
+	 * @param session The session in which the {@link Blob} will be used.
+	 * @return the Blob
+	 */
+	public static Blob createBlob(InputStream stream, long length, Session session) {
+		// todo : wrap?
+		return getLobCreator( session ).createBlob( stream, length );
+	}
+
+	/**
+	 * Create a new {@link Blob}. The returned object will be initially immutable.
+	 * <p/>
+	 * NOTE: this method will read the entire contents of the incoming stream in order to properly
+	 * handle the {@link Blob#length()} method.  If you do not want the stream read, use the
+	 * {@link #createBlob(InputStream,long)} version instead.
+	 *
+	 * @param stream a binary stream
+	 * @return the Blob
+	 * @throws IOException Indicates an I/O problem accessing the stream
+	 * @deprecated Use {@link #createBlob(InputStream, long, Session)} instead
+	 */
 	public static Blob createBlob(InputStream stream) throws IOException {
-		return new SerializableBlob( new BlobImpl( stream, stream.available() ) );
+		ByteArrayOutputStream buffer = new ByteArrayOutputStream( stream.available() );
+		StreamUtils.copy( stream, buffer );
+		return createBlob( buffer.toByteArray() );
 	}
 
 	/**
-	 * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
+	 * Create a new {@link Clob}. The returned object will be initially immutable.
 	 *
-	 * @param string a <tt>String</tt>
+	 * @param string The string data
+	 * @return The created {@link Clob}
+	 * @deprecated Use {@link #createClob(String, Session)} instead
 	 */
 	public static Clob createClob(String string) {
-		return new SerializableClob( new ClobImpl( string ) );
+		return NonContextualLobCreator.INSTANCE.wrap(
+				NonContextualLobCreator.INSTANCE.createClob( string )
+		);
 	}
 
 	/**
-	 * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
+	 * Create a new {@link Clob}.
 	 *
+	 * @param string The string data
+	 * @param session The session in which the {@link Clob} will be used.
+	 * @return The created {@link Clob}
+	 */
+	public static Clob createClob(String string, Session session) {
+		// todo : wrap?
+		return getLobCreator( session ).createClob( string );
+	}
+
+	/**
+	 * Create a new {@link Clob}. The returned object will be initially immutable.
+	 *
 	 * @param reader a character stream
 	 * @param length the number of characters in the stream
+	 * @return The created {@link Clob}
+	 * @deprecated Use {@link #createClob(Reader,long,Session)} instead
 	 */
 	public static Clob createClob(Reader reader, int length) {
-		return new SerializableClob( new ClobImpl( reader, length ) );
+		return NonContextualLobCreator.INSTANCE.wrap(
+				NonContextualLobCreator.INSTANCE.createClob( reader, length )
+		);
 	}
 
 	/**
+	 * Create a new {@link Clob}. The returned object will be initially immutable.
+	 *
+	 * @param reader a character stream
+	 * @param length the number of characters in the stream
+	 * @return The created {@link Clob}
+	 * @deprecated Use {@link #createClob(Reader,long,Session)} instead
+	 */
+	public static Clob createClob(Reader reader, long length) {
+		return NonContextualLobCreator.INSTANCE.wrap(
+				NonContextualLobCreator.INSTANCE.createClob( reader, length ) 
+		);
+	}
+
+	/**
+	 * Create a new {@link Clob}.
+	 *
+	 * @param reader a character stream
+	 * @param length the number of characters in the stream
+	 * @param session The session in which the {@link Clob} will be used.
+	 * @return The created {@link Clob}
+	 */
+	public static Clob createClob(Reader reader, long length, Session session) {
+		return getLobCreator( session ).createClob( reader, length );
+	}
+
+	/**
 	 * Close an <tt>Iterator</tt> created by <tt>iterate()</tt> immediately,
 	 * instead of waiting until the session is closed or disconnected.
 	 *
@@ -460,8 +571,7 @@
 	 *
 	 * @param proxy The potential proxy
 	 * @param propertyName the name of a persistent attribute of the object
-	 * @return true if the named property of the object is not listed as uninitialized
-	 * @return false if the object is an uninitialized proxy, or the named property is uninitialized
+	 * @return true if the named property of the object is not listed as uninitialized; false otherwise
 	 */
 	public static boolean isPropertyInitialized(Object proxy, String propertyName) {
 		

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -28,6 +28,7 @@
 
 import org.hibernate.ConnectionReleaseMode;
 import org.hibernate.EntityMode;
+import org.hibernate.engine.jdbc.JdbcSupport;
 import org.hibernate.tuple.entity.EntityTuplizerFactory;
 import org.hibernate.tuple.component.ComponentTuplizerFactory;
 import org.hibernate.cache.QueryCacheFactory;
@@ -98,6 +99,7 @@
 	private boolean checkNullability;
 //	private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907
 //	private BytecodeProvider bytecodeProvider;
+	private JdbcSupport jdbcSupport;
 
 	/**
 	 * Package protected constructor
@@ -299,9 +301,13 @@
 //		return componentTuplizerFactory;
 //	}
 
+	public JdbcSupport getJdbcSupport() {
+		return jdbcSupport;
+	}
 
-// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+	// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 //	void setShowSqlEnabled(boolean b) {
 //		showSql = b;
 //	}
@@ -502,8 +508,11 @@
 //		this.componentTuplizerFactory = componentTuplizerFactory;
 //	}
 
+	void setJdbcSupport(JdbcSupport jdbcSupport) {
+		this.jdbcSupport = jdbcSupport;
+	}
 
-//	public BytecodeProvider getBytecodeProvider() {
+	//	public BytecodeProvider getBytecodeProvider() {
 //		return bytecodeProvider;
 //	}
 //

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -38,6 +38,8 @@
 import org.hibernate.ConnectionReleaseMode;
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
+import org.hibernate.engine.jdbc.JdbcSupport;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
 import org.hibernate.bytecode.BytecodeProvider;
 import org.hibernate.cache.QueryCacheFactory;
 import org.hibernate.cache.RegionFactory;
@@ -97,6 +99,7 @@
 		boolean metaReportsDDLCausesTxnCommit = false;
 		boolean metaReportsDDLInTxnSupported = true;
 		Dialect dialect = null;
+		JdbcSupport jdbcSupport = null;
 
 		// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
 		// The need for it is intended to be alleviated with future developement, thus it is
@@ -115,6 +118,7 @@
 					log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
 
 					dialect = DialectFactory.buildDialect( props, conn );
+					jdbcSupport = JdbcSupportLoader.loadJdbcSupport( conn );
 
 					metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
 					metaSupportsBatchUpdates = meta.supportsBatchUpdates();
@@ -145,6 +149,10 @@
 		settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
 		settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
 		settings.setDialect( dialect );
+		if ( jdbcSupport == null ) {
+			jdbcSupport = JdbcSupportLoader.loadJdbcSupport( null );
+		}
+		settings.setJdbcSupport( jdbcSupport );
 
 		//use dialect default properties
 		final Properties properties = new Properties();

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Blob;
+import java.sql.Clob;
+
+/**
+ * Convenient base class for proxy-based LobCreator for handling wrapping.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractLobCreator implements LobCreator {
+	/**
+	 * {@inheritDoc}
+	 */
+	public Blob wrap(Blob blob) {
+		return SerializableBlobProxy.generateProxy( blob );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob wrap(Clob clob) {
+		if ( SerializableNClobProxy.isNClob( clob ) ) {
+			return SerializableNClobProxy.generateProxy( clob );
+		}
+		else {
+			return SerializableClobProxy.generateProxy( clob );
+		}
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,32 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+/**
+ * Marker interface for non-contextually created {@link java.sql.Blob} instances..
+ *
+ * @author Steve Ebersole
+ */
+public interface BlobImplementer {
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,154 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * Manages aspects of proxying {@link Blob Blobs} for non-contextual creation, including proxy creation and
+ * handling proxy invocations.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class BlobProxy implements InvocationHandler {
+	private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, BlobImplementer.class };
+
+	private InputStream stream;
+	private long length;
+	private boolean needsReset = false;
+
+	/**
+	 * Ctor used to build {@link Blob} from byte array.
+	 *
+	 * @param bytes The byte array
+	 * @see #generateProxy(byte[])
+	 */
+	private BlobProxy(byte[] bytes) {
+		this.stream = new ByteArrayInputStream( bytes );
+		this.length = bytes.length;
+	}
+
+	/**
+	 * Ctor used to build {@link Blob} from a stream.
+	 *
+	 * @param stream The binary stream
+	 * @param length The length of the stream
+	 * @see #generateProxy(java.io.InputStream, long)
+	 */
+	private BlobProxy(InputStream stream, long length) {
+		this.stream = stream;
+		this.length = length;
+	}
+
+	private long getLength() {
+		return length;
+	}
+
+	private InputStream getStream() throws SQLException {
+		try {
+			if (needsReset) {
+				stream.reset();
+			}
+		}
+		catch ( IOException ioe) {
+			throw new SQLException("could not reset reader");
+		}
+		needsReset = true;
+		return stream;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 *
+	 * @throws UnsupportedOperationException if any methods other than {@link Blob#length()}
+	 * or {@link Blob#getBinaryStream} are invoked.
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if ( "length".equals( method.getName() ) ) {
+			return new Long( getLength() );
+		}
+		if ( "getBinaryStream".equals( method.getName() ) && method.getParameterTypes().length == 0 ) {
+			return getStream();
+		}
+		if ( "free".equals( method.getName() ) ) {
+			stream.close();
+			return null;
+		}
+		throw new UnsupportedOperationException( "Blob may not be manipulated from creating session" );
+	}
+
+	/**
+	 * Generates a BlobImpl proxy using byte data.
+	 *
+	 * @param bytes The data to be created as a Blob.
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Blob generateProxy(byte[] bytes) {
+		return ( Blob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				PROXY_INTERFACES,
+				new BlobProxy( bytes )
+		);
+	}
+
+	/**
+	 * Generates a BlobImpl proxy using a given number of bytes from an InputStream.
+	 *
+	 * @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.
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Blob generateProxy(InputStream stream, long length) {
+		return ( Blob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				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 = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = BlobImplementer.class.getClassLoader();
+		}
+		return cl;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,32 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+/**
+ * Marker interface for non-contextually created {@link java.sql.Clob} instances..
+ *
+ * @author Steve Ebersole
+ */
+public interface ClobImplementer {
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,168 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Manages aspects of proxying {@link Clob Clobs} for non-contextual creation, including proxy creation and
+ * handling proxy invocations.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class ClobProxy implements InvocationHandler {
+	private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, ClobImplementer.class };
+
+	private Reader reader;
+	private long length;
+	private boolean needsReset = false;
+
+
+	/**
+	 * Ctor used to build {@link Clob} from string data.
+	 *
+	 * @param string The byte array
+	 * @see #generateProxy(String)
+	 */
+	protected ClobProxy(String string) {
+		reader = new StringReader(string);
+		length = string.length();
+	}
+
+	/**
+	 * Ctor used to build {@link Clob} from a reader.
+	 *
+	 * @param reader The character reader.
+	 * @param length The length of the reader stream.
+	 * @see #generateProxy(java.io.Reader, long)
+	 */
+	protected ClobProxy(Reader reader, long length) {
+		this.reader = reader;
+		this.length = length;
+	}
+
+	protected long getLength() {
+		return length;
+	}
+
+	protected InputStream getAsciiStream() throws SQLException {
+		resetIfNeeded();
+		return new ReaderInputStream( reader );
+	}
+
+	protected Reader getCharacterStream() throws SQLException {
+		resetIfNeeded();
+		return reader;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 *
+	 * @throws UnsupportedOperationException if any methods other than {@link Clob#length()},
+	 * {@link Clob#getAsciiStream()}, or {@link Clob#getCharacterStream()} are invoked.
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if ( "length".equals( method.getName() ) ) {
+			return new Long( getLength() );
+		}
+		if ( "getAsciiStream".equals( method.getName() ) ) {
+			return getAsciiStream();
+		}
+		if ( "getCharacterStream".equals( method.getName() ) ) {
+			return getCharacterStream();
+		}
+		if ( "free".equals( method.getName() ) ) {
+			reader.close();
+			return null;
+		}
+		throw new UnsupportedOperationException( "Clob may not be manipulated from creating session" );
+	}
+
+	protected void resetIfNeeded() throws SQLException {
+		try {
+			if ( needsReset ) {
+				reader.reset();
+			}
+		}
+		catch ( IOException ioe ) {
+			throw new SQLException( "could not reset reader" );
+		}
+		needsReset = true;
+	}
+
+	/**
+	 * Generates a {@link Clob} proxy using the string data.
+	 *
+	 * @param string The data to be wrapped as a {@link Clob}.
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Clob generateProxy(String string) {
+		return ( Clob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				PROXY_INTERFACES,
+				new ClobProxy( string )
+		);
+	}
+
+	/**
+	 * Generates a {@link Clob} proxy using a character reader of given length.
+	 *
+	 * @param reader The character reader
+	 * @param length The length of the character reader
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Clob generateProxy(Reader reader, long length) {
+		return ( Clob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				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 = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = ClobImplementer.class.getClassLoader();
+		}
+		return cl;
+	}
+}

Copied: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java (from rev 17373, core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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;
+
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Cache of column-name -> column-index resolutions
+ *
+ * @author Steve Ebersole
+ */
+public class ColumnNameCache {
+	public static final float LOAD_FACTOR = .75f;
+
+	private final Map columnNameToIndexCache;
+
+	public ColumnNameCache(int columnCount) {
+		// should *not* need to grow beyond the size of the total number of columns in the rs
+		this.columnNameToIndexCache = new HashMap( columnCount + (int)( columnCount * LOAD_FACTOR ) + 1, LOAD_FACTOR );
+	}
+
+	public int getIndexForColumnName(String columnName, ResultSet rs) throws SQLException {
+		Integer cached = ( Integer ) columnNameToIndexCache.get( columnName );
+		if ( cached != null ) {
+			return cached.intValue();
+		}
+		else {
+			int index = rs.findColumn( columnName );
+			columnNameToIndexCache.put( columnName, new Integer(index) );
+			return index;
+		}
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,237 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * {@link LobCreator} implementation using contextual creation against the JDBC {@link java.sql.Connection} class's LOB creation
+ * methods.
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class ContextualLobCreator extends AbstractLobCreator implements LobCreator {
+	private LobCreationContext lobCreationContext;
+
+	public ContextualLobCreator(LobCreationContext lobCreationContext) {
+		this.lobCreationContext = lobCreationContext;
+	}
+
+	/**
+	 * Create the basic contextual BLOB reference.
+	 *
+	 * @return The created BLOB reference.
+	 */
+	public Blob createBlob() {
+		return ( Blob ) lobCreationContext.execute( CREATE_BLOB_CALLBACK );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Blob createBlob(byte[] bytes) {
+		try {
+			Blob blob = createBlob();
+			blob.setBytes( 1, bytes );
+			return blob;
+		}
+		catch ( SQLException e ) {
+			throw new IllegalStateException( "Unable to set BLOB bytes after creation", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Blob createBlob(InputStream inputStream, long length) {
+		try {
+			Blob blob = createBlob();
+			OutputStream byteStream = blob.setBinaryStream( 1 );
+			StreamUtils.copy( inputStream, byteStream );
+			byteStream.flush();
+			byteStream.close();
+			// todo : validate length written versus length given?
+			return blob;
+		}
+		catch ( SQLException e ) {
+			throw new IllegalStateException( "Unable to prepare BLOB binary stream for writing", e );
+		}
+		catch ( IOException e ) {
+			throw new IllegalStateException( "Unable to write stream contents to BLOB", e );
+		}
+	}
+
+	/**
+	 * Create the basic contextual CLOB reference.
+	 *
+	 * @return The created CLOB reference.
+	 */
+	public Clob createClob() {
+		return ( Clob ) lobCreationContext.execute( CREATE_CLOB_CALLBACK );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createClob(String string) {
+		try {
+			Clob clob = createClob();
+			clob.setString( 1, string );
+			return clob;
+		}
+		catch ( SQLException e ) {
+			throw new IllegalStateException( "Unable to set CLOB string after creation", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createClob(Reader reader, long length) {
+		try {
+			Clob clob = createClob();
+			Writer writer = clob.setCharacterStream( 1 );
+			StreamUtils.copy( reader, writer );
+			writer.flush();
+			writer.close();
+			return clob;
+		}
+		catch ( SQLException e ) {
+			throw new IllegalStateException( "Unable to prepare CLOB stream for writing", e );
+		}
+		catch ( IOException e ) {
+			throw new IllegalStateException( "Unable to write CLOB stream content", e );
+		}
+	}
+
+	/**
+	 * Create the basic contextual NCLOB reference.
+	 *
+	 * @return The created NCLOB reference.
+	 */
+	public Clob createNClob() {
+		return ( Clob ) lobCreationContext.execute( CREATE_NCLOB_CALLBACK );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createNClob(String string) {
+		try {
+			Clob clob = createNClob();
+			clob.setString( 1, string );
+			return clob;
+		}
+		catch ( SQLException e ) {
+			throw new IllegalStateException( "Unable to set NCLOB string after creation", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createNClob(Reader reader, long length) {
+		try {
+			Clob clob = createNClob();
+			Writer writer = clob.setCharacterStream( 1 );
+			StreamUtils.copy( reader, writer );
+			writer.flush();
+			writer.close();
+			return clob;
+		}
+		catch ( SQLException e ) {
+			throw new IllegalStateException( "Unable to prepare NCLOB stream for writing", e );
+		}
+		catch ( IOException e ) {
+			throw new IllegalStateException( "Unable to write NCLOB stream content", e );
+		}
+	}
+
+
+	private static final Class[] CREATION_METHOD_SIG = new Class[0];
+	private static final Object[] CREATION_METHOD_ARGS = new Object[0];
+
+	private static final LobCreationContext.Callback CREATE_BLOB_CALLBACK;
+	private static final LobCreationContext.Callback CREATE_CLOB_CALLBACK;
+	private static final LobCreationContext.Callback CREATE_NCLOB_CALLBACK;
+
+	static {
+		CREATE_BLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createBlob" ) );
+		CREATE_CLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createClob" ) );
+		CREATE_NCLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createNClob" ) );
+	}
+
+	private static class CallbackImpl implements LobCreationContext.Callback {
+		private final Method creationMethod;
+
+		private CallbackImpl(Method creationMethod) {
+			this.creationMethod = creationMethod;
+		}
+
+		public Object executeOnConnection(Connection connection) throws SQLException {
+			try {
+				return creationMethod.invoke( connection, CREATION_METHOD_ARGS );
+			}
+			catch ( InvocationTargetException e ) {
+				if ( e.getTargetException() instanceof SQLException ) {
+					throw ( SQLException ) e.getTargetException();
+				}
+				else {
+					throw new HibernateException( "Exception invoking " + creationMethod.getName(), e.getTargetException() );
+				}
+			}
+			catch ( AbstractMethodError e ) {
+				// this again is a big big error...
+				throw new IllegalStateException( "Useable implementation of " + creationMethod.getName() + " not found.", e );
+			}
+			catch ( IllegalAccessException e ) {
+				// this again is a big big error...
+				throw new IllegalStateException( "Illegal access attempt on JDBC method " + creationMethod.getName(), e );
+			}
+		}
+	}
+
+	private static Method getConnectionlobCreationMethod(String methodName) {
+		try {
+			return Connection.class.getMethod( methodName, CREATION_METHOD_SIG );
+		}
+		catch ( NoSuchMethodException e ) {
+			// this is a big big error if we get here and these methods are not part of the Connection interface...
+			throw new IllegalStateException( "JDBC driver did not implement " + methodName, e );
+		}
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.ResultSet;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportImpl implements JdbcSupport {
+	private final boolean useContextualLobCreation;
+
+	public JdbcSupportImpl(boolean useContextualLobCreation) {
+		this.useContextualLobCreation = useContextualLobCreation;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public LobCreator getLobCreator() {
+		return NonContextualLobCreator.INSTANCE;
+	}
+
+	public LobCreator getLobCreator(LobCreationContext lobCreationContext) {
+		if ( useContextualLobCreation ) {
+			return new ContextualLobCreator( lobCreationContext );
+		}
+		else {
+			return NonContextualLobCreator.INSTANCE;
+		}
+	}
+
+	public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache) {
+		return ResultSetWrapperProxy.generateProxy( resultSet, columnNameCache );
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,97 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Connection;
+import java.lang.reflect.Method;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Builds {@link JdbcSupport} instances based on the capabilities of the environment.
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportLoader {
+	private static final Logger log = LoggerFactory.getLogger( JdbcSupportLoader.class );
+
+	/**
+	 * The public factory method for obtaining the appropriate (accoring to given JDBC {@link java.sql.Connection})
+	 * {@link JdbcSupport}.
+	 *
+	 * @param jdbcConnection A JDBC {@link java.sql.Connection} which can be used to gauge the drivers level of support,
+	 * specifically for creating LOB references.
+	 * @return An appropriate {@link JdbcSupport} instance.
+	 */
+	public static JdbcSupport loadJdbcSupport(Connection jdbcConnection) {
+		return new JdbcSupportImpl( useContextualLobCreation( jdbcConnection ) );
+	}
+
+	private static final Class[] NO_ARG_SIG = new Class[0];
+	private static final Object[] NO_ARGS = new Object[0];
+
+	/**
+	 * Basically here we are simply checking whether we can call the {@link Connection} methods for
+	 * LOB creation added in JDBC 4.  We not only check whether the {@link Connection} declares these methods,
+	 * but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply
+	 * throwing an exception).
+	 *
+	 * @param jdbcConnection The connection whcih can be used in level-of-support testing.
+	 * @return True if the connection can be used to create LOBs; false otherwise.
+	 */
+	private static boolean useContextualLobCreation(Connection jdbcConnection) {
+		if ( jdbcConnection == null ) {
+			return false;
+		}
+
+		try {
+			Class connectionClass = Connection.class;
+			Method createClobMethod = connectionClass.getMethod( "createClob", NO_ARG_SIG );
+			if ( createClobMethod.getDeclaringClass().equals( Connection.class ) ) {
+				// If we get here we are running in a jdk 1.6 (jdbc 4) environment...
+				// Further check to make sure the driver actually implements the LOB creation methods.  We
+				// check against createClob() as indicative of all; should we check against all 3 explicitly?
+				try {
+					Object clob = createClobMethod.invoke( jdbcConnection, NO_ARGS );
+					try {
+						Method freeMethod = clob.getClass().getMethod( "free", NO_ARG_SIG );
+						freeMethod.invoke( clob, NO_ARGS );
+					}
+					catch ( Throwable ignore ) {
+						log.trace( "Unable to free CLOB created to test createClob() implementation : " + ignore );
+					}
+					return true;
+				}
+				catch ( Throwable t ) {
+					log.info( "createClob() method threw error : " + t );
+				}
+			}
+		}
+		catch ( NoSuchMethodException ignore ) {
+		}
+
+		return false;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.hibernate.JDBCException;
+import org.hibernate.exception.SQLExceptionConverter;
+
+/**
+ * Provides callback access into the context in which the LOB is to be created.  Mainly this is useful
+ * for gaining access to the JDBC {@link Connection} for use in JDBC 4 environments.
+ *
+ * @author Steve Ebersole
+ */
+public interface LobCreationContext {
+	/**
+	 * The callback contract for making use of the JDBC {@link Connection}.
+	 */
+	public static interface Callback {
+		/**
+		 * Perform whatever actions are necessary using the provided JDBC {@link Connection}.
+		 *
+		 * @param connection The JDBC {@link Connection}.
+		 * @return The created LOB.
+		 * @throws SQLException
+		 */
+		public Object executeOnConnection(Connection connection) throws SQLException;
+	}
+
+	/**
+	 * Execute the given callback, making sure it has access to a viable JDBC {@link Connection}.
+	 *
+	 * @param callback The callback to execute .
+	 * @return The LOB created by the callback.
+	 */
+	public Object execute(Callback callback);
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,34 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+/**
+ * Marker interface for non-contextually created java.sql.NClob instances..
+ * <p/>
+ * java.sql.NClob is a new type introduced in JDK 1.6 (JDBC 4)
+ *
+ * @author Steve Ebersole
+ */
+public interface NClobImplementer {
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,105 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Clob;
+import java.io.Reader;
+import java.lang.reflect.Proxy;
+
+/**
+ * Manages aspects of proxying java.sql.NClobs for non-contextual creation, including proxy creation and
+ * handling proxy invocations.
+ * <p/>
+ * Generated proxies are typed as {@link java.sql.Clob} (java.sql.NClob extends {@link java.sql.Clob}) and in JDK 1.6 environments, they
+ * are also typed to java.sql.NClob
+ *
+ * @author Steve Ebersole
+ */
+public class NClobProxy extends ClobProxy {
+	public static final Class[] PROXY_INTERFACES = new Class[] { determineNClobInterface(), NClobImplementer.class };
+
+	private static Class determineNClobInterface() {
+		// java.sql.NClob is a simple marker interface extending java.sql.Clob.  So if java.sql.NClob is not available
+		// on the classloader, just use java.sql.Clob
+		try {
+			return getProxyClassLoader().loadClass( "java.sql.NClob" );
+		}
+		catch ( ClassNotFoundException e ) {
+			return Clob.class;
+		}
+	}
+
+	protected NClobProxy(String string) {
+		super( string );
+	}
+
+	protected NClobProxy(Reader reader, long length) {
+		super( reader, length );
+	}
+
+	/**
+	 * Generates a {@link java.sql.Clob} proxy using the string data.
+	 *
+	 * @param string The data to be wrapped as a {@link java.sql.Clob}.
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Clob generateProxy(String string) {
+		return ( Clob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				PROXY_INTERFACES,
+				new ClobProxy( string )
+		);
+	}
+
+	/**
+	 * Generates a {@link Clob} proxy using a character reader of given length.
+	 *
+	 * @param reader The character reader
+	 * @param length The length of the character reader
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Clob generateProxy(Reader reader, long length) {
+		return ( Clob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				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 = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = NClobImplementer.class.getClassLoader();
+		}
+		return cl;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,85 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * {@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}.
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class NonContextualLobCreator extends AbstractLobCreator implements LobCreator {
+	public static final NonContextualLobCreator INSTANCE = new NonContextualLobCreator();
+
+	private NonContextualLobCreator() {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Blob createBlob(byte[] bytes) {
+		return BlobProxy.generateProxy( bytes );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Blob createBlob(InputStream stream, long length) {
+		return BlobProxy.generateProxy( stream, length );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createClob(String string) {
+		return ClobProxy.generateProxy( string );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createClob(Reader reader, long length) {
+		return ClobProxy.generateProxy( reader, length );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createNClob(String string) {
+		return NClobProxy.generateProxy( string );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Clob createNClob(Reader reader, long length) {
+		return NClobProxy.generateProxy( reader, length );
+	}
+}

Copied: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java (from rev 17373, core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Exposes a {@link Reader} as an {@link InputStream}.
+ * 
+ * @author Gavin King
+ */
+public class ReaderInputStream extends InputStream {
+	private Reader reader;
+	
+	public ReaderInputStream(Reader reader) {
+		this.reader = reader;
+	}
+	
+	public int read() throws IOException {
+		return reader.read();
+	}
+	
+}


Property changes on: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
___________________________________________________________________
Name: svn:executable
   + *

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,194 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.util.JDBCExceptionReporter;
+
+/**
+ * A proxy for a ResultSet delegate, responsible for locally caching the columnName-to-columnIndex resolution that
+ * has been found to be inefficient in a few vendor's drivers (i.e., Oracle and Postgres).
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class ResultSetWrapperProxy implements InvocationHandler {
+	private static final Logger log = LoggerFactory.getLogger( ResultSetWrapperProxy.class );
+	private static final Class[] PROXY_INTERFACES = new Class[] { ResultSet.class };
+
+	private final ResultSet rs;
+	private final ColumnNameCache columnNameCache;
+
+	private ResultSetWrapperProxy(ResultSet rs, ColumnNameCache columnNameCache) {
+		this.rs = rs;
+		this.columnNameCache = columnNameCache;
+	}
+
+	/**
+	 * Generates a proxy wrapping the ResultSet.
+	 *
+	 * @param resultSet The resultSet to wrap.
+	 * @param columnNameCache The cache storing data for converting column names to column indexes.
+	 * @return The generated proxy.
+	 */
+	public static ResultSet generateProxy(ResultSet resultSet, ColumnNameCache columnNameCache) {
+		return ( ResultSet ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				PROXY_INTERFACES,
+				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 = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = ResultSet.class.getClassLoader();
+		}
+		return cl;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if ( "findColumn".equals( method.getName() ) ) {
+			return new Integer( findColumn( ( String ) args[0] ) );
+		}
+
+		if ( isFirstArgColumnLabel( method, args ) ) {
+			try {
+				int columnIndex = findColumn( ( String ) args[0] );
+				return invokeMethod(
+						locateCorrespondingColumnIndexMethod( method ), buildColumnIndexMethodArgs( args, columnIndex )
+				);
+			}
+			catch ( SQLException ex ) {
+				StringBuffer buf = new StringBuffer()
+						.append( "Exception getting column index for column: [" )
+						.append( args[0] )
+						.append( "].\nReverting to using: [" )
+						.append( args[0] )
+						.append( "] as first argument for method: [" )
+						.append( method )
+						.append( "]" );
+				JDBCExceptionReporter.logExceptions( ex, buf.toString() );
+			}
+			catch ( NoSuchMethodException ex ) {
+				StringBuffer buf = new StringBuffer()
+						.append( "Exception switching from method: [" )
+						.append( method )
+						.append( "] to a method using the column index. Reverting to using: [" )
+						.append( method )
+						.append( "]" );
+				if ( log.isWarnEnabled() ) {
+					log.warn( buf.toString() );
+				}
+			}
+		}
+		return invokeMethod( method, args );
+	}
+
+	/**
+	 * Locate the column index corresponding to the given column name via the cache.
+	 *
+	 * @param columnName The column name to resolve into an index.
+	 * @return The column index corresponding to the given column name.
+	 * @throws SQLException if the ResultSet object does not contain columnName or a database access error occurs
+	 */
+	private int findColumn(String columnName) throws SQLException {
+		return columnNameCache.getIndexForColumnName( columnName, rs );
+	}
+
+	private boolean isFirstArgColumnLabel(Method method, Object args[]) {
+		// method name should start with either get or update
+		if ( ! ( method.getName().startsWith( "get" ) || method.getName().startsWith( "update" ) ) ) {
+			return false;
+		}
+
+		// method should have arguments, and have same number as incoming arguments
+		if ( ! ( method.getParameterTypes().length > 0 && args.length == method.getParameterTypes().length ) ) {
+			return false;
+		}
+
+		// The first argument should be a String (the column name)
+		//noinspection RedundantIfStatement
+		if ( ! ( String.class.isInstance( args[0] ) && method.getParameterTypes()[0].equals( String.class ) ) ) {
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * For a given {@link ResultSet} method passed a column name, locate the corresponding method passed the same
+	 * parameters but the column index.
+	 *
+	 * @param columnNameMethod The method passed the column name
+	 * @return The corresponding method passed the column index.
+	 * @throws NoSuchMethodException Should never happen, but...
+	 */
+	private Method locateCorrespondingColumnIndexMethod(Method columnNameMethod) throws NoSuchMethodException {
+		Class actualParameterTypes[] = new Class[columnNameMethod.getParameterTypes().length];
+		actualParameterTypes[0] = int.class;
+		System.arraycopy(
+				columnNameMethod.getParameterTypes(),
+				1,
+				actualParameterTypes,
+				1,
+				columnNameMethod.getParameterTypes().length - 1
+		);
+		return columnNameMethod.getDeclaringClass().getMethod( columnNameMethod.getName(), actualParameterTypes );
+	}
+
+	private Object[] buildColumnIndexMethodArgs(Object[] incomingArgs, int columnIndex) {
+		Object actualArgs[] = new Object[incomingArgs.length];
+		actualArgs[0] = new Integer( columnIndex );
+		System.arraycopy( incomingArgs, 1, actualArgs, 1, incomingArgs.length - 1 );
+		return actualArgs;
+	}
+
+	private Object invokeMethod(Method method, Object args[]) throws Throwable {
+		try {
+			return method.invoke( rs, args );
+		}
+		catch ( InvocationTargetException e ) {
+			throw e.getTargetException();
+		}
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,112 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Blob;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Manages aspects of proxying {@link Blob Blobs} to add serializability.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class SerializableBlobProxy implements InvocationHandler, Serializable {
+	private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, WrappedBlob.class, Serializable.class };
+
+	private transient final Blob blob;
+
+	/**
+	 * Builds a serializable {@link Blob} wrapper around the given {@link Blob}.
+	 *
+	 * @param blob The {@link Blob} to be wrapped.
+	 * @see
+	 */
+	private SerializableBlobProxy(Blob blob) {
+		this.blob = blob;
+	}
+
+	public Blob getWrappedBlob() {
+		if ( blob == null ) {
+			throw new IllegalStateException( "Blobs may not be accessed after serialization" );
+		}
+		else {
+			return blob;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if ( "getWrappedBlob".equals( method.getName() ) ) {
+			return getWrappedBlob();
+		}
+		try {
+			return method.invoke( getWrappedBlob(), args );
+		}
+		catch ( AbstractMethodError e ) {
+			throw new HibernateException( "The JDBC driver does not implement the method: " + method, e );
+		}
+		catch ( InvocationTargetException e ) {
+			throw e.getTargetException();
+		}
+	}
+
+	/**
+	 * Generates a SerializableBlob proxy wrapping the provided Blob object.
+	 *
+	 * @param blob The Blob to wrap.
+	 *
+	 * @return The generated proxy.
+	 */
+	public static Blob generateProxy(Blob blob) {
+		return ( Blob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				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 = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = WrappedBlob.class.getClassLoader();
+		}
+		return cl;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,111 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.sql.Clob;
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Manages aspects of proxying {@link Clob Clobs} to add serializability.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class SerializableClobProxy implements InvocationHandler, Serializable {
+	private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, WrappedClob.class, Serializable.class };
+
+	private transient final Clob clob;
+
+	/**
+	 * Builds a serializable {@link java.sql.Clob} wrapper around the given {@link java.sql.Clob}.
+	 *
+	 * @param clob The {@link java.sql.Clob} to be wrapped.
+	 * @see #generateProxy(java.sql.Clob)
+	 */
+	protected SerializableClobProxy(Clob clob) {
+		this.clob = clob;
+	}
+
+	public Clob getWrappedClob() {
+		if ( clob == null ) {
+			throw new IllegalStateException( "Clobs may not be accessed after serialization" );
+		}
+		else {
+			return clob;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if ( "getWrappedClob".equals( method.getName() ) ) {
+			return getWrappedClob();
+		}
+		try {
+			return method.invoke( getWrappedClob(), args );
+		}
+		catch ( AbstractMethodError e ) {
+			throw new HibernateException( "The JDBC driver does not implement the method: " + method, e );
+		}
+		catch ( InvocationTargetException e ) {
+			throw e.getTargetException();
+		}
+	}
+
+	/**
+	 * Generates a SerializableClobProxy proxy wrapping the provided Clob object.
+	 *
+	 * @param clob The Clob to wrap.
+	 * @return The generated proxy.
+	 */
+	public static Clob generateProxy(Clob clob) {
+		return ( Clob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				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 = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = WrappedClob.class.getClassLoader();
+		}
+		return cl;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,92 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Clob;
+import java.lang.reflect.Proxy;
+
+/**
+ * Manages aspects of proxying java.sql.NClobs to add serializability.
+ *
+ * @author Steve Ebersole
+ */
+public class SerializableNClobProxy extends SerializableClobProxy {
+	private static final Class NCLOB_CLASS = loadNClobClassIfAvailable();
+
+	private static Class loadNClobClassIfAvailable() {
+		try {
+			return getProxyClassLoader().loadClass( "java.sql.NClob" );
+		}
+		catch ( ClassNotFoundException e ) {
+			return null;
+		}
+	}
+
+	private static final Class[] PROXY_INTERFACES = new Class[] { determineNClobInterface(), WrappedClob.class };
+
+	private static Class determineNClobInterface() {
+		// java.sql.NClob is a simple marker interface extending java.sql.Clob.  So if java.sql.NClob is not available
+		// on the classloader, just use java.sql.Clob
+		return NCLOB_CLASS == null ? Clob.class : NCLOB_CLASS;
+	}
+
+	public static boolean isNClob(Clob clob) {
+		return NCLOB_CLASS != null && NCLOB_CLASS.isInstance( clob );
+	}
+
+	/**
+	 * Builds a serializable {@link java.sql.Clob} wrapper around the given {@link java.sql.Clob}.
+	 *
+	 * @param clob The {@link java.sql.Clob} to be wrapped.
+	 *
+	 * @see #generateProxy(java.sql.Clob)
+	 */
+	protected SerializableNClobProxy(Clob clob) {
+		super( clob );
+	}
+
+	/**
+	 * Generates a SerializableClobProxy proxy wrapping the provided Clob object.
+	 *
+	 * @param clob The Clob to wrap.
+	 * @return The generated proxy.
+	 */
+	public static Clob generateProxy(Clob clob) {
+		return ( Clob ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+				PROXY_INTERFACES,
+				new SerializableNClobProxy( 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() {
+		return SerializableClobProxy.getProxyClassLoader();
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,71 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * Stream copying utilities
+ *
+ * @author Steve Ebersole
+ */
+public class StreamUtils {
+	public static final int DEFAULT_CHUNK_SIZE = 1024;
+
+	public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException {
+		return copy( inputStream, outputStream, DEFAULT_CHUNK_SIZE );
+	}
+
+	public static long copy(InputStream inputStream, OutputStream outputStream, int bufferSize) throws IOException {
+		byte[] buffer = new byte[bufferSize];
+		long count = 0;
+		int n;
+		while ( -1 != ( n = inputStream.read( buffer ) ) ) {
+			outputStream.write( buffer, 0, n );
+			count += n;
+		}
+		return count;
+
+	}
+
+	public static long copy(Reader reader, Writer writer) throws IOException {
+		return copy( reader, writer, DEFAULT_CHUNK_SIZE );
+	}
+
+	public static long copy(Reader reader, Writer writer, int bufferSize) throws IOException {
+		char[] buffer = new char[bufferSize];
+		long count = 0;
+		int n;
+		while ( -1 != ( n = reader.read( buffer ) ) ) {
+			writer.write( buffer, 0, n );
+			count += n;
+		}
+		return count;
+
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Blob;
+
+/**
+ * Contract for {@link Blob} wrappers.
+ *
+ * @author Steve Ebersole
+ */
+public interface WrappedBlob {
+	/**
+	 * Retrieve the wrapped {@link Blob} reference
+	 *
+	 * @return The wrapped {@link Blob} reference
+	 */
+	public Blob getWrappedBlob();
+}

Added: core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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;
+
+import java.sql.Clob;
+
+/**
+ * Contract for {@link Clob} wrappers.
+ *
+ * @author Steve Ebersole
+ */
+public interface WrappedClob {
+	/**
+	 * Retrieve the wrapped {@link java.sql.Blob} reference
+	 *
+	 * @return The wrapped {@link java.sql.Blob} reference
+	 */
+	public Clob getWrappedClob();
+}

Modified: core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -77,6 +77,7 @@
 import org.hibernate.engine.StatefulPersistenceContext;
 import org.hibernate.engine.Status;
 import org.hibernate.engine.LoadQueryInfluencers;
+import org.hibernate.engine.jdbc.LobCreationContext;
 import org.hibernate.engine.query.FilterQueryPlan;
 import org.hibernate.engine.query.HQLQueryPlan;
 import org.hibernate.engine.query.NativeSQLQueryPlan;
@@ -140,7 +141,7 @@
  * @author Gavin King
  */
 public final class SessionImpl extends AbstractSessionImpl 
-		implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
+		implements EventSource, org.hibernate.classic.Session, JDBCContext.Context, LobCreationContext {
 
 	// todo : need to find a clean way to handle the "event source" role
 	// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
@@ -2001,6 +2002,23 @@
 		oos.writeObject( childSessionsByEntityMode );
 	}
 
+	public Object execute(Callback callback) {
+		Connection connection = jdbcContext.getConnectionManager().getConnection();
+		try {
+			return callback.executeOnConnection( connection );
+		}
+		catch ( SQLException e ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					e,
+					"Error creating contextual LOB : " + e.getMessage()
+			);
+		}
+		finally {
+			jdbcContext.getConnectionManager().afterStatement();
+		}
+	}
+
 	private class CoordinatingEntityNameResolver implements EntityNameResolver {
 		public String resolveEntityName(Object entity) {
 			String entityName = interceptor.getEntityName( entity );

Deleted: core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -1,56 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
- *
- * 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.jdbc;
-
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Implementation of ColumnNameCache.
- *
- * @author Steve Ebersole
- */
-public class ColumnNameCache {
-
-	private final Map columnNameToIndexCache;
-
-	public ColumnNameCache(int columnCount) {
-		// should *not* need to grow beyond the size of the total number of columns in the rs
-		this.columnNameToIndexCache = new HashMap( columnCount );
-	}
-
-	public int getIndexForColumnName(String columnName, ResultSetWrapper rs)throws SQLException {
-		Integer cached = ( Integer ) columnNameToIndexCache.get( columnName );
-		if ( cached != null ) {
-			return cached.intValue();
-		}
-		else {
-			int index = rs.getTarget().findColumn( columnName );
-			columnNameToIndexCache.put( columnName, new Integer(index) );
-			return index;
-		}
-	}
-}

Deleted: core/trunk/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -1,642 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
- *
- * 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.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Map;
-
-/**
- * A ResultSet delegate, responsible for locally caching the columnName-to-columnIndex
- * resolution that has been found to be inefficient in a few vendor's drivers (i.e., Oracle
- * and Postgres).
- *
- * @author Steve Ebersole
- */
-public class ResultSetWrapper implements ResultSet {
-
-	private ResultSet rs;
-	private ColumnNameCache columnNameCache;
-
-	public ResultSetWrapper(ResultSet resultSet, ColumnNameCache columnNameCache) {
-		this.rs = resultSet;
-		this.columnNameCache = columnNameCache;
-	}
-
-	/*package*/ ResultSet getTarget() {
-		return rs;
-	}
-
-
-	// ResultSet impl ("overridden") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Overridden version to utilize local caching of the column indexes by name
-	 * to improve performance for those drivers which are known to not support
-	 * such caching by themselves.
-	 * <p/>
-	 * This implementation performs the caching based on the upper case version
-	 * of the given column name.
-	 *
-	 * @param columnName The column name to resolve into an index.
-	 * @return The column index corresponding to the given column name.
-	 * @throws SQLException - if the ResultSet object does not contain
-	 * columnName or a database access error occurs
-	 */
-	public int findColumn(String columnName) throws SQLException {
-		return columnNameCache.getIndexForColumnName( columnName, this );
-	}
-
-	public Array getArray(String colName) throws SQLException {
-		return rs.getArray( findColumn(colName) );
-	}
-
-	public void updateArray(String columnName, Array x) throws SQLException {
-		rs.updateArray( findColumn(columnName), x );
-	}
-
-	public InputStream getAsciiStream(String columnName) throws SQLException {
-		return rs.getAsciiStream( findColumn(columnName) );
-	}
-
-	public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException {
-		rs.updateAsciiStream( findColumn(columnName), x, length );
-	}
-
-	public BigDecimal getBigDecimal(String columnName) throws SQLException {
-		return rs.getBigDecimal( findColumn(columnName) );
-	}
-
-	public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
-		return rs.getBigDecimal( findColumn(columnName), scale );
-	}
-
-	public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
-		rs.updateBigDecimal( findColumn(columnName), x );
-	}
-
-	public InputStream getBinaryStream(String columnName) throws SQLException {
-		return rs.getBinaryStream( findColumn(columnName) );
-	}
-
-	public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException {
-		rs.updateBinaryStream( findColumn(columnName), x, length );
-	}
-
-	public Blob getBlob(String columnName) throws SQLException {
-		return rs.getBlob( findColumn(columnName) );
-	}
-
-	public void updateBlob(String columnName, Blob x) throws SQLException {
-		rs.updateBlob( findColumn(columnName), x );
-	}
-
-	public boolean getBoolean(String columnName) throws SQLException {
-		return rs.getBoolean( findColumn(columnName) );
-	}
-
-	public void updateBoolean(String columnName, boolean x) throws SQLException {
-		rs.updateBoolean( findColumn(columnName), x );
-	}
-
-	public byte getByte(String columnName) throws SQLException {
-		return rs.getByte( findColumn(columnName) );
-	}
-
-	public void updateByte(String columnName, byte x) throws SQLException {
-		rs.updateByte( findColumn(columnName), x );
-	}
-
-	public byte[] getBytes(String columnName) throws SQLException {
-		return rs.getBytes( findColumn(columnName) );
-	}
-
-	public void updateBytes(String columnName, byte[] x) throws SQLException {
-		rs.updateBytes( findColumn(columnName), x );
-	}
-
-	public Reader getCharacterStream(String columnName) throws SQLException {
-		return rs.getCharacterStream( findColumn(columnName) );
-	}
-
-	public void updateCharacterStream(String columnName, Reader x, int length) throws SQLException {
-		rs.updateCharacterStream( findColumn(columnName), x, length );
-	}
-
-	public Clob getClob(String columnName) throws SQLException {
-		return rs.getClob( findColumn(columnName) );
-	}
-
-	public void updateClob(String columnName, Clob x) throws SQLException {
-		rs.updateClob( findColumn(columnName), x );
-	}
-
-	public Date getDate(String columnName) throws SQLException {
-		return rs.getDate( findColumn(columnName) );
-	}
-
-	public Date getDate(String columnName, Calendar cal) throws SQLException {
-		return rs.getDate( findColumn(columnName), cal );
-	}
-
-	public void updateDate(String columnName, Date x) throws SQLException {
-		rs.updateDate( findColumn(columnName), x );
-	}
-
-	public double getDouble(String columnName) throws SQLException {
-		return rs.getDouble( findColumn(columnName) );
-	}
-
-	public void updateDouble(String columnName, double x) throws SQLException {
-		rs.updateDouble( findColumn(columnName), x );
-	}
-
-	public float getFloat(String columnName) throws SQLException {
-		return rs.getFloat( findColumn(columnName) );
-	}
-
-	public void updateFloat(String columnName, float x) throws SQLException {
-		rs.updateFloat( findColumn(columnName), x );
-	}
-
-	public int getInt(String columnName) throws SQLException {
-		return rs.getInt( findColumn(columnName) );
-	}
-
-	public void updateInt(String columnName, int x) throws SQLException {
-		rs.updateInt( findColumn(columnName), x );
-	}
-
-	public long getLong(String columnName) throws SQLException {
-		return rs.getLong( findColumn(columnName) );
-	}
-
-	public void updateLong(String columnName, long x) throws SQLException {
-		rs.updateLong( findColumn(columnName), x );
-	}
-
-	public Object getObject(String columnName) throws SQLException {
-		return rs.getObject( findColumn(columnName) );
-	}
-
-	public Object getObject(String columnName, Map map) throws SQLException {
-		return rs.getObject( findColumn(columnName), map );
-	}
-
-	public void updateObject(String columnName, Object x) throws SQLException {
-		rs.updateObject( findColumn(columnName), x );
-	}
-
-	public void updateObject(String columnName, Object x, int scale) throws SQLException {
-		rs.updateObject( findColumn(columnName), x, scale );
-	}
-
-	public Ref getRef(String columnName) throws SQLException {
-		return rs.getRef( findColumn(columnName) );
-	}
-
-	public void updateRef(String columnName, Ref x) throws SQLException {
-		rs.updateRef( findColumn(columnName), x );
-	}
-
-	public short getShort(String columnName) throws SQLException {
-		return rs.getShort( findColumn(columnName) );
-	}
-
-	public void updateShort(String columnName, short x) throws SQLException {
-		rs.updateShort( findColumn(columnName), x );
-	}
-
-	public String getString(String columnName) throws SQLException {
-		return rs.getString( findColumn(columnName) );
-	}
-
-	public void updateString(String columnName, String x) throws SQLException {
-		rs.updateString( findColumn(columnName), x );
-	}
-
-	public Time getTime(String columnName) throws SQLException {
-		return rs.getTime( findColumn(columnName) );
-	}
-
-	public Time getTime(String columnName, Calendar cal) throws SQLException {
-		return rs.getTime( findColumn(columnName), cal );
-	}
-
-	public void updateTime(String columnName, Time x) throws SQLException {
-		rs.updateTime( findColumn(columnName), x );
-	}
-
-	public Timestamp getTimestamp(String columnName) throws SQLException {
-		return rs.getTimestamp( findColumn(columnName) );
-	}
-
-	public void updateTimestamp(String columnName, Timestamp x) throws SQLException {
-		rs.updateTimestamp( findColumn(columnName), x );
-	}
-
-	public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
-		return rs.getTimestamp( findColumn(columnName), cal );
-	}
-
-	public InputStream getUnicodeStream(String columnName) throws SQLException {
-		return rs.getUnicodeStream( findColumn(columnName) );
-	}
-
-	public URL getURL(String columnName) throws SQLException {
-		return rs.getURL( findColumn(columnName) );
-	}
-
-	public void updateNull(String columnName) throws SQLException {
-		rs.updateNull( findColumn(columnName) );
-	}
-
-
-	// ResultSet impl (delegated) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public int getConcurrency() throws SQLException {
-		return rs.getConcurrency();
-	}
-
-	public int getFetchDirection() throws SQLException {
-		return rs.getFetchDirection();
-	}
-
-	public int getFetchSize() throws SQLException {
-		return rs.getFetchSize();
-	}
-
-	public int getRow() throws SQLException {
-		return rs.getRow();
-	}
-
-	public int getType() throws SQLException {
-		return rs.getType();
-	}
-
-	public void afterLast() throws SQLException {
-		rs.afterLast();
-	}
-
-	public void beforeFirst() throws SQLException {
-		rs.beforeFirst();
-	}
-
-	public void cancelRowUpdates() throws SQLException {
-		rs.cancelRowUpdates();
-	}
-
-	public void clearWarnings() throws SQLException {
-		rs.clearWarnings();
-	}
-
-	public void close() throws SQLException {
-		rs.close();
-	}
-
-	public void deleteRow() throws SQLException {
-		rs.deleteRow();
-	}
-
-	public void insertRow() throws SQLException {
-		rs.insertRow();
-	}
-
-	public void moveToCurrentRow() throws SQLException {
-		rs.moveToCurrentRow();
-	}
-
-	public void moveToInsertRow() throws SQLException {
-		rs.moveToInsertRow();
-	}
-
-	public void refreshRow() throws SQLException {
-		rs.refreshRow();
-	}
-
-	public void updateRow() throws SQLException {
-		rs.updateRow();
-	}
-
-	public boolean first() throws SQLException {
-		return rs.first();
-	}
-
-	public boolean isAfterLast() throws SQLException {
-		return rs.isAfterLast();
-	}
-
-	public boolean isBeforeFirst() throws SQLException {
-		return rs.isBeforeFirst();
-	}
-
-	public boolean isFirst() throws SQLException {
-		return rs.isFirst();
-	}
-
-	public boolean isLast() throws SQLException {
-		return rs.isLast();
-	}
-
-	public boolean last() throws SQLException {
-		return rs.last();
-	}
-
-	public boolean next() throws SQLException {
-		return rs.next();
-	}
-
-	public boolean previous() throws SQLException {
-		return rs.previous();
-	}
-
-	public boolean rowDeleted() throws SQLException {
-		return rs.rowDeleted();
-	}
-
-	public boolean rowInserted() throws SQLException {
-		return rs.rowInserted();
-	}
-
-	public boolean rowUpdated() throws SQLException {
-		return rs.rowUpdated();
-	}
-
-	public boolean wasNull() throws SQLException {
-		return rs.wasNull();
-	}
-
-	public byte getByte(int columnIndex) throws SQLException {
-		return rs.getByte(columnIndex);
-	}
-
-	public double getDouble(int columnIndex) throws SQLException {
-		return rs.getDouble(columnIndex);
-	}
-
-	public float getFloat(int columnIndex) throws SQLException {
-		return rs.getFloat(columnIndex);
-	}
-
-	public int getInt(int columnIndex) throws SQLException {
-		return rs.getInt(columnIndex);
-	}
-
-	public long getLong(int columnIndex) throws SQLException {
-		return rs.getLong(columnIndex);
-	}
-
-	public short getShort(int columnIndex) throws SQLException {
-		return rs.getShort(columnIndex);
-	}
-
-	public void setFetchDirection(int direction) throws SQLException {
-		rs.setFetchDirection(direction);
-	}
-
-	public void setFetchSize(int rows) throws SQLException {
-		rs.setFetchSize(rows);
-	}
-
-	public void updateNull(int columnIndex) throws SQLException {
-		rs.updateNull(columnIndex);
-	}
-
-	public boolean absolute(int row) throws SQLException {
-		return rs.absolute(row);
-	}
-
-	public boolean getBoolean(int columnIndex) throws SQLException {
-		return rs.getBoolean(columnIndex);
-	}
-
-	public boolean relative(int rows) throws SQLException {
-		return rs.relative(rows);
-	}
-
-	public byte[] getBytes(int columnIndex) throws SQLException {
-		return rs.getBytes(columnIndex);
-	}
-
-	public void updateByte(int columnIndex, byte x) throws SQLException {
-		rs.updateByte(columnIndex, x);
-	}
-
-	public void updateDouble(int columnIndex, double x) throws SQLException {
-		rs.updateDouble(columnIndex, x);
-	}
-
-	public void updateFloat(int columnIndex, float x) throws SQLException {
-		rs.updateFloat(columnIndex, x);
-	}
-
-	public void updateInt(int columnIndex, int x) throws SQLException {
-		rs.updateInt(columnIndex, x);
-	}
-
-	public void updateLong(int columnIndex, long x) throws SQLException {
-		rs.updateLong(columnIndex, x);
-	}
-
-	public void updateShort(int columnIndex, short x) throws SQLException {
-		rs.updateShort(columnIndex, x);
-	}
-
-	public void updateBoolean(int columnIndex, boolean x) throws SQLException {
-		rs.updateBoolean(columnIndex, x);
-	}
-
-	public void updateBytes(int columnIndex, byte[] x) throws SQLException {
-		rs.updateBytes(columnIndex, x);
-	}
-
-	public InputStream getAsciiStream(int columnIndex) throws SQLException {
-		return rs.getAsciiStream(columnIndex);
-	}
-
-	public InputStream getBinaryStream(int columnIndex) throws SQLException {
-		return rs.getBinaryStream(columnIndex);
-	}
-
-	public InputStream getUnicodeStream(int columnIndex) throws SQLException {
-		return rs.getUnicodeStream(columnIndex);
-	}
-
-	public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
-		rs.updateAsciiStream(columnIndex, x, length);
-	}
-
-	public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
-		rs.updateBinaryStream(columnIndex, x, length);
-	}
-
-	public Reader getCharacterStream(int columnIndex) throws SQLException {
-		return rs.getCharacterStream(columnIndex);
-	}
-
-	public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
-		rs.updateCharacterStream(columnIndex, x, length);
-	}
-
-	public Object getObject(int columnIndex) throws SQLException {
-		return rs.getObject(columnIndex);
-	}
-
-	public void updateObject(int columnIndex, Object x) throws SQLException {
-		rs.updateObject(columnIndex, x);
-	}
-
-	public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
-		rs.updateObject(columnIndex, x, scale);
-	}
-
-	public String getCursorName() throws SQLException {
-		return rs.getCursorName();
-	}
-
-	public String getString(int columnIndex) throws SQLException {
-		return rs.getString(columnIndex);
-	}
-
-	public void updateString(int columnIndex, String x) throws SQLException {
-		rs.updateString(columnIndex, x);
-	}
-
-	public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
-		return rs.getBigDecimal(columnIndex);
-	}
-
-	public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
-		return rs.getBigDecimal(columnIndex, scale);
-	}
-
-	public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
-		rs.updateBigDecimal(columnIndex, x);
-	}
-
-	public URL getURL(int columnIndex) throws SQLException {
-		return rs.getURL(columnIndex);
-	}
-
-	public Array getArray(int columnIndex) throws SQLException {
-		return rs.getArray(columnIndex);
-	}
-
-	public void updateArray(int columnIndex, Array x) throws SQLException {
-		rs.updateArray(columnIndex, x);
-	}
-
-	public Blob getBlob(int columnIndex) throws SQLException {
-		return rs.getBlob(columnIndex);
-	}
-
-	public void updateBlob(int columnIndex, Blob x) throws SQLException {
-		rs.updateBlob(columnIndex, x);
-	}
-
-	public Clob getClob(int columnIndex) throws SQLException {
-		return rs.getClob(columnIndex);
-	}
-
-	public void updateClob(int columnIndex, Clob x) throws SQLException {
-		rs.updateClob(columnIndex, x);
-	}
-
-	public Date getDate(int columnIndex) throws SQLException {
-		return rs.getDate(columnIndex);
-	}
-
-	public void updateDate(int columnIndex, Date x) throws SQLException {
-		rs.updateDate(columnIndex, x);
-	}
-
-	public Ref getRef(int columnIndex) throws SQLException {
-		return rs.getRef(columnIndex);
-	}
-
-	public void updateRef(int columnIndex, Ref x) throws SQLException {
-		rs.updateRef(columnIndex, x);
-	}
-
-	public ResultSetMetaData getMetaData() throws SQLException {
-		return rs.getMetaData();
-	}
-
-	public SQLWarning getWarnings() throws SQLException {
-		return rs.getWarnings();
-	}
-
-	public Statement getStatement() throws SQLException {
-		return rs.getStatement();
-	}
-
-	public Time getTime(int columnIndex) throws SQLException {
-		return rs.getTime(columnIndex);
-	}
-
-	public void updateTime(int columnIndex, Time x) throws SQLException {
-		rs.updateTime(columnIndex, x);
-	}
-
-	public Timestamp getTimestamp(int columnIndex) throws SQLException {
-		return rs.getTimestamp(columnIndex);
-	}
-
-	public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
-		rs.updateTimestamp(columnIndex, x);
-	}
-
-	public Object getObject(int columnIndex, Map map) throws SQLException {
-		return rs.getObject( columnIndex, map );
-	}
-
-	public Date getDate(int columnIndex, Calendar cal) throws SQLException {
-		return rs.getDate(columnIndex, cal);
-	}
-
-	public Time getTime(int columnIndex, Calendar cal) throws SQLException {
-		return rs.getTime(columnIndex, cal);
-	}
-
-	public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
-		return rs.getTimestamp(columnIndex, cal);
-	}
-}
-

Modified: core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/Loader.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/loader/Loader.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -1,10 +1,10 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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
@@ -20,7 +20,6 @@
  * Free Software Foundation, Inc.
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
- *
  */
 package org.hibernate.loader;
 
@@ -63,6 +62,7 @@
 import org.hibernate.engine.SubselectFetch;
 import org.hibernate.engine.TwoPhaseLoad;
 import org.hibernate.engine.TypedValue;
+import org.hibernate.engine.jdbc.ColumnNameCache;
 import org.hibernate.event.EventSource;
 import org.hibernate.event.PostLoadEvent;
 import org.hibernate.event.PreLoadEvent;
@@ -70,8 +70,6 @@
 import org.hibernate.hql.HolderInstantiator;
 import org.hibernate.impl.FetchingScrollableResultsImpl;
 import org.hibernate.impl.ScrollableResultsImpl;
-import org.hibernate.jdbc.ColumnNameCache;
-import org.hibernate.jdbc.ResultSetWrapper;
 import org.hibernate.persister.collection.CollectionPersister;
 import org.hibernate.persister.entity.EntityPersister;
 import org.hibernate.persister.entity.Loadable;
@@ -1839,7 +1837,9 @@
 		if ( session.getFactory().getSettings().isWrapResultSetsEnabled() ) {
 			try {
 				log.debug("Wrapping result set [" + rs + "]");
-				return new ResultSetWrapper( rs, retreiveColumnNameToIndexCache( rs ) );
+				return session.getFactory()
+						.getSettings()
+						.getJdbcSupport().wrap( rs, retreiveColumnNameToIndexCache( rs ) );
 			}
 			catch(SQLException e) {
 				log.info("Error wrapping result set", e);

Modified: core/trunk/core/src/main/java/org/hibernate/type/BlobType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BlobType.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/type/BlobType.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -36,11 +36,14 @@
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
 import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
 import org.hibernate.engine.Mapping;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
-import org.hibernate.lob.SerializableBlob;
+import org.hibernate.engine.jdbc.BlobImplementer;
+import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
 import org.hibernate.util.ArrayHelper;
 
 /**
@@ -48,135 +51,223 @@
  * @author Gavin King
  */
 public class BlobType extends AbstractType {
+	/**
+	 * {@inheritDoc}
+	 */
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			boolean[] settable,
+			SessionImplementor session) throws HibernateException, SQLException {
+		if ( settable[0] ) {
+			set( st, value, index, session );
+		}
+	}
 
-	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		
-		if (value==null) {
-			st.setNull(index, Types.BLOB);
+	/**
+	 * {@inheritDoc}
+	 */
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			SessionImplementor session) throws HibernateException, SQLException {
+		set( st, value, index, session );
+	}
+
+	public void set(
+			PreparedStatement st,
+			Object value,
+			int index,
+			SessionImplementor session) throws HibernateException, SQLException {
+		if ( value == null ) {
+			st.setNull( index, Types.BLOB );
+			return;
 		}
+
+		Blob blob = ( Blob ) value;
+
+		if ( WrappedBlob.class.isInstance( blob ) ) {
+			blob = ( (WrappedBlob) value ).getWrappedBlob();
+		}
+
+		final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob()
+				&& BlobImplementer.class.isInstance( blob );
+
+		if ( useInputStream ) {
+			st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() );
+		}
 		else {
-			
-			if (value instanceof SerializableBlob) {
-				value = ( (SerializableBlob) value ).getWrappedBlob();
-			}
-		
-			final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob() && 
-				(value instanceof BlobImpl);
-			
-			if ( useInputStream ) {
-				BlobImpl blob = (BlobImpl) value;
-				st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() );
-			}
-			else {
-				st.setBlob(index, (Blob) value);
-			}
-			
+			st.setBlob( index, blob );
 		}
-		
 	}
 
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		Blob value = rs.getBlob(name);
-		return rs.wasNull() ? null : new SerializableBlob(value);
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object nullSafeGet(
+			ResultSet rs,
+			String name,
+			SessionImplementor session,
+			Object owner) throws HibernateException, SQLException {
+		return get( rs, name, Hibernate.getLobCreator( session ) );
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object nullSafeGet(
+			ResultSet rs,
+			String[] names,
+			SessionImplementor session,
+			Object owner) throws HibernateException, SQLException {
+		return get( rs, names[0], Hibernate.getLobCreator( session ) );
+	}
+
+	/**
+	 * A method to extract the BLOB value from a result set.
+	 *
+	 * @param rs The result set
+	 * @param name The name of the column containing the BLOB
+	 *
+	 * @return The BLOB
+	 *
+	 * @throws SQLException Indicates a problem accessing the result set
+	 *
+	 * @deprecated Use {@link #get(ResultSet,String,LobCreator)} instead
+	 */
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return get( rs, name, NonContextualLobCreator.INSTANCE );
+	}
+
+	public Object get(ResultSet rs, String name, LobCreator lobCreator) throws SQLException {
+		Blob value = rs.getBlob( name );
+		return rs.wasNull() ? null : lobCreator.wrap( value );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public Class getReturnedClass() {
 		return Blob.class;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
 		return x == y;
 	}
 	
+	/**
+	 * {@inheritDoc}
+	 */
 	public int getHashCode(Object x, EntityMode entityMode) {
 		return System.identityHashCode(x);
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public int compare(Object x, Object y, EntityMode entityMode) {
 		return 0; //lobs cannot be compared
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public String getName() {
 		return "blob";
 	}
-	
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-		throws HibernateException {
+		throws UnsupportedOperationException {
 		throw new UnsupportedOperationException("Blobs are not cacheable");
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)  {
 		return value;
 	}
 	
+	/**
+	 * {@inheritDoc}
+	 */
 	public Object fromXMLNode(Node xml, Mapping factory) {
 		throw new UnsupportedOperationException("todo");
 	}
 	
+	/**
+	 * {@inheritDoc}
+	 */
 	public int getColumnSpan(Mapping mapping) {
 		return 1;
 	}
 	
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isMutable() {
 		return false;
 	}
 	
-	public Object nullSafeGet(ResultSet rs, String name,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get(rs, name);
-	}
-	
-	public Object nullSafeGet(ResultSet rs, String[] names,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get( rs, names[0] );
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			boolean[] settable, SessionImplementor session)
-			throws HibernateException, SQLException {
-		if ( settable[0] ) set(st, value, index, session);
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			SessionImplementor session) throws HibernateException, SQLException {
-		set(st, value, index, session);
-	}
-	
-	public Object replace(Object original, Object target,
-			SessionImplementor session, Object owner, Map copyCache)
-			throws HibernateException {
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object replace(
+			Object original,
+			Object target,
+			SessionImplementor session,
+			Object owner,
+			Map copyCache) throws HibernateException {
 		//Blobs are ignored by merge()
 		return target;
 	}
-	
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public int[] sqlTypes(Mapping mapping) throws MappingException {
 		return new int[] { Types.BLOB };
 	}
 	
+	/**
+	 * {@inheritDoc}
+	 */
 	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) {
 		throw new UnsupportedOperationException("todo");
 	}
 	
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
+	/**
+	 * {@inheritDoc}
+	 */
+	public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
 		return value==null ? "null" : value.toString();
 	}
-	
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean[] toColumnNullness(Object value, Mapping mapping) {
 		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
 	}
 
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isDirty(
+			Object old,
+			Object current,
+			boolean[] checkable,
+			SessionImplementor session) throws HibernateException {
 		return checkable[0] && isDirty(old, current, session);
 	}
 
 }
 
-
-
-
-
-

Modified: core/trunk/core/src/main/java/org/hibernate/type/ClobType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ClobType.java	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/core/src/main/java/org/hibernate/type/ClobType.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -40,8 +40,10 @@
 import org.hibernate.engine.Mapping;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.ClobImpl;
-import org.hibernate.lob.SerializableClob;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
+import org.hibernate.engine.jdbc.WrappedClob;
+import org.hibernate.engine.jdbc.ClobImplementer;
 import org.hibernate.util.ArrayHelper;
 
 /**
@@ -50,38 +52,89 @@
  */
 public class ClobType extends AbstractType {
 
-	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		
-		if (value==null) {
-			st.setNull(index, Types.CLOB);
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			boolean[] settable,
+			SessionImplementor session) throws SQLException {
+		if ( settable[0] ) {
+			set( st, value, index, session );
 		}
+	}
+
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			SessionImplementor session) throws SQLException {
+		set( st, value, index, session );
+	}
+
+	public void set(
+			PreparedStatement st,
+			Object value,
+			int index,
+			SessionImplementor session) throws SQLException {
+		if ( value == null ) {
+			st.setNull( index, Types.CLOB );
+			return;
+		}
+
+		Clob clob = ( Clob ) value;
+
+		if ( WrappedClob.class.isInstance( clob ) ) {
+			clob = ( (WrappedClob) value ).getWrappedClob();
+		}
+
+		final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob()
+				&& ClobImplementer.class.isInstance( clob );
+
+		if ( useInputStream ) {
+			st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() );
+		}
 		else {
-		
-			if (value instanceof SerializableClob) {
-				value = ( (SerializableClob) value ).getWrappedClob();
-			}
-		
-			final boolean useReader = session.getFactory().getDialect().useInputStreamToInsertBlob() && 
-				(value instanceof ClobImpl);
-			
-			if ( useReader ) {
-				ClobImpl clob = (ClobImpl) value;
-				st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() );
-			}
-			else {
-				st.setClob(index, (Clob) value);
-			}
-			
+			st.setClob( index, clob );
 		}
-		
 	}
 
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		Clob value = rs.getClob(name);
-		return rs.wasNull() ? null : new SerializableClob(value);
+	public Object nullSafeGet(
+			ResultSet rs,
+			String name,
+			SessionImplementor session,
+			Object owner) throws SQLException {
+		return get( rs, name, Hibernate.getLobCreator( session ) );
 	}
 
+	public Object nullSafeGet(
+			ResultSet rs,
+			String[] names,
+			SessionImplementor session,
+			Object owner) throws SQLException {
+		return get( rs, names[0], Hibernate.getLobCreator( session ) );
+	}
+
+	/**
+	 * A method to extract the CLOB value from a result set.
+	 *
+	 * @param rs The result set
+	 * @param name The name of the column containing the CLOB
+	 *
+	 * @return The CLOB
+	 *
+	 * @throws SQLException Indicates a problem accessing the result set
+	 *
+	 * @deprecated Use {@link #get(ResultSet,String,LobCreator)} instead
+	 */
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return get( rs, name, NonContextualLobCreator.INSTANCE );
+	}
+
+	public Clob get(ResultSet rs, String name, LobCreator lobCreator) throws SQLException {
+		Clob value = rs.getClob( name );
+		return rs.wasNull() ? null : lobCreator.wrap( value );
+	}
+
 	public Class getReturnedClass() {
 		return Clob.class;
 	}
@@ -123,29 +176,6 @@
 		return false;
 	}
 	
-	public Object nullSafeGet(ResultSet rs, String name,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get(rs, name);
-	}
-	
-	public Object nullSafeGet(ResultSet rs, String[] names,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get( rs, names[0] );
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			boolean[] settable, SessionImplementor session)
-			throws HibernateException, SQLException {
-		if ( settable[0] ) set(st, value, index, session);
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			SessionImplementor session) throws HibernateException, SQLException {
-		set(st, value, index, session);
-	}
-	
 	public Object replace(Object original, Object target,
 			SessionImplementor session, Object owner, Map copyCache)
 			throws HibernateException {


Property changes on: core/trunk/jdbc3-testing
___________________________________________________________________
Name: svn:ignore
   + target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover


Added: core/trunk/jdbc3-testing/pom.xml
===================================================================
--- core/trunk/jdbc3-testing/pom.xml	                        (rev 0)
+++ core/trunk/jdbc3-testing/pom.xml	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,61 @@
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+  ~ third-party contributors as indicated by either @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
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.5.0-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>hibernate-jdbc3-testing</artifactId>
+    <packaging>jar</packaging>
+
+    <name>JDBC3-JdbcSupport Testing</name>
+    <description>Test support of JDBC3 through JdbcSupport</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+		    <groupId>postgresql</groupId>
+		    <artifactId>postgresql</artifactId>
+		    <version>8.4-701.jdbc4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+		    <groupId>mysql</groupId>
+		    <artifactId>mysql-connector-java</artifactId>
+		    <version>5.1.10</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
+

Added: core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
===================================================================
--- core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java	                        (rev 0)
+++ core/trunk/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.jdbc3;
+
+import java.sql.SQLException;
+import java.sql.Blob;
+import java.sql.Clob;
+
+import junit.framework.TestCase;
+
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
+import org.hibernate.engine.jdbc.BlobImplementer;
+import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.engine.jdbc.WrappedClob;
+import org.hibernate.engine.jdbc.ClobImplementer;
+import org.hibernate.engine.jdbc.NClobImplementer;
+
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportTest extends TestCase {
+	public void testLobCreator() throws ClassNotFoundException, SQLException {
+		final LobCreationContext lobCreationContext = new LobCreationContext() {
+			public Object execute(Callback callback) {
+				fail( "Unexpeted call to getConnection" );
+				return null;
+			}
+		};
+
+		LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( null ).getLobCreator( lobCreationContext );
+
+		Blob blob = lobCreator.createBlob( new byte[] {} );
+		assertTrue( blob instanceof BlobImplementer );
+		blob = lobCreator.wrap( blob );
+		assertTrue( blob instanceof WrappedBlob );
+
+		Clob clob = lobCreator.createClob( "Hi" );
+		assertTrue( clob instanceof ClobImplementer );
+		clob = lobCreator.wrap( clob );
+		assertTrue( clob instanceof WrappedClob );
+
+		Clob nclob = lobCreator.createNClob( "Hi" );
+		assertTrue( nclob instanceof NClobImplementer );
+		nclob = lobCreator.wrap( nclob );
+		assertTrue( nclob instanceof WrappedClob );
+
+	}
+}

Added: core/trunk/jdbc3-testing/src/test/resources/log4j.properties
===================================================================
--- core/trunk/jdbc3-testing/src/test/resources/log4j.properties	                        (rev 0)
+++ core/trunk/jdbc3-testing/src/test/resources/log4j.properties	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,30 @@
+#
+# Hibernate, Relational Persistence for Idiomatic Java
+#
+# Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+# third-party contributors as indicated by either @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
+#
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+
+log4j.rootLogger=info, stdout


Property changes on: core/trunk/jdbc4-testing
___________________________________________________________________
Name: svn:ignore
   + target
local
*.ipr
*.iws
*.iml
.classpath
.project
.settings
.nbattrs
*.log
*.properties
.clover


Added: core/trunk/jdbc4-testing/pom.xml
===================================================================
--- core/trunk/jdbc4-testing/pom.xml	                        (rev 0)
+++ core/trunk/jdbc4-testing/pom.xml	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,94 @@
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+  ~ third-party contributors as indicated by either @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
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.5.0-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <properties>
+        <!-- TODO : move this to local settings.xml -->
+        <jdbc4_jdk>/opt/java/jdk-1.6</jdbc4_jdk>
+    </properties>
+
+    <artifactId>hibernate-jdbc4-testing</artifactId>
+    <name>JDBC4-JdbcSupport Testing</name>
+    <description>Test support of JDBC4 through JdbcSupport</description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                    <verbose>true</verbose>
+                    <fork>true</fork>
+                    <executable>${jdbc4_jdk}/bin/javac</executable>
+                    <compilerVersion>1.6</compilerVersion>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <jvm>${jdbc4_jdk}/bin/java</jvm>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+		    <groupId>postgresql</groupId>
+		    <artifactId>postgresql</artifactId>
+		    <version>8.4-701.jdbc4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+		    <groupId>mysql</groupId>
+		    <artifactId>mysql-connector-java</artifactId>
+		    <version>5.1.10</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.oracle</groupId>
+            <artifactId>ojdbc6</artifactId>
+            <version>11.1.0.7.0</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
+

Added: core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
===================================================================
--- core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java	                        (rev 0)
+++ core/trunk/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,276 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.jdbc4;
+
+import java.sql.SQLException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.NClob;
+
+import junit.framework.TestCase;
+
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
+import org.hibernate.engine.jdbc.ContextualLobCreator;
+import org.hibernate.engine.jdbc.BlobImplementer;
+import org.hibernate.engine.jdbc.ClobImplementer;
+import org.hibernate.engine.jdbc.NClobImplementer;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
+import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.engine.jdbc.WrappedClob;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportTest extends TestCase {
+	private interface Envionment {
+		public String getDriver();
+		public String getUrl();
+		public String getUser();
+		public String getPass();
+
+		public void verifyCreator(LobCreator lobCreator);
+		public void verifyBlob(Blob blob);
+		public void verifyClob(Clob clob);
+		public void verifyNClob(Clob nclob);
+	}
+
+	private abstract class ContextualEnvironment implements Envionment {
+		public void verifyCreator(LobCreator lobCreator) {
+			assertTrue( lobCreator instanceof ContextualLobCreator );
+		}
+
+		public void verifyBlob(Blob blob) {
+			assertFalse( blob instanceof BlobImplementer );
+		}
+
+		public void verifyClob(Clob clob) {
+			assertFalse( clob instanceof ClobImplementer );
+		}
+
+		public void verifyNClob(Clob nclob) {
+			assertFalse( nclob instanceof NClobImplementer );
+		}
+	}
+
+	private abstract class NonContextualEnvironment implements Envionment {
+		public void verifyCreator(LobCreator lobCreator) {
+			assertTrue( lobCreator instanceof NonContextualLobCreator );
+		}
+
+		public void verifyBlob(Blob blob) {
+			assertTrue( blob instanceof BlobImplementer );
+		}
+
+		public void verifyClob(Clob clob) {
+			assertTrue( clob instanceof ClobImplementer );
+		}
+
+		public void verifyNClob(Clob nclob) {
+			assertTrue( nclob instanceof NClobImplementer );
+		}
+	}
+
+	private Envionment POSTGRESQL = new NonContextualEnvironment() {
+		public String getDriver() {
+			return "org.postgresql.Driver";
+		}
+
+		public String getUrl() {
+			return "jdbc:postgresql://vmg03.mw.lab.eng.bos.redhat.com:5432:platformae";
+		}
+
+		public String getUser() {
+			return "sebersole";
+		}
+
+		public String getPass() {
+			return "sebersole";
+		}
+	};
+
+	private Envionment MYSQL = new ContextualEnvironment() {
+		public String getDriver() {
+			return "com.mysql.jdbc.Driver";
+		}
+
+		public String getUrl() {
+			return "jdbc:mysql://vmg02.mw.lab.eng.bos.redhat.com/sebersole";
+		}
+
+		public String getUser() {
+			return "sebersole";
+		}
+
+		public String getPass() {
+			return "sebersole";
+		}
+	};
+
+	private Envionment ORACLE9i = new ContextualEnvironment() {
+		public String getDriver() {
+			return "oracle.jdbc.driver.OracleDriver";
+		}
+
+		public String getUrl() {
+			return "jdbc:oracle:thin:@dev20.qa.atl.jboss.com:1521:qa";
+		}
+
+		public String getUser() {
+			return "sebersole";
+		}
+
+		public String getPass() {
+			return "sebersole";
+		}
+	};
+
+	private Envionment ORACLE10g = new ContextualEnvironment() {
+		public String getDriver() {
+			return "oracle.jdbc.driver.OracleDriver";
+		}
+
+		public String getUrl() {
+			return "jdbc:oracle:thin:@vmg05.mw.lab.eng.bos.redhat.com:1521:qaora10";
+		}
+
+		public String getUser() {
+			return "sebersole";
+		}
+
+		public String getPass() {
+			return "sebersole";
+		}
+	};
+
+	private Envionment ORACLE11g = new ContextualEnvironment() {
+		public String getDriver() {
+			return "oracle.jdbc.driver.OracleDriver";
+		}
+
+		public String getUrl() {
+			return "jdbc:oracle:thin:@dev04.qa.atl2.redhat.com:1521:qaora11";
+		}
+
+		public String getUser() {
+			return "sebersole";
+		}
+
+		public String getPass() {
+			return "sebersole";
+		}
+	};
+
+	private Envionment ORACLE_RAC = new ContextualEnvironment() {
+		public String getDriver() {
+			return "oracle.jdbc.driver.OracleDriver";
+		}
+
+		public String getUrl() {
+			return "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=vmg24-vip.mw.lab.eng.bos.redhat.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=vmg25-vip.mw.lab.eng.bos.redhat.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=qarac.jboss))";
+		}
+
+		public String getUser() {
+			return "sebersole";
+		}
+
+		public String getPass() {
+			return "sebersole";
+		}
+	};
+
+	private Envionment envionment = ORACLE11g;
+
+	protected void setUp() throws Exception {
+		Class.forName( envionment.getDriver() );
+	}
+
+	public void testConnectedLobCreator() throws SQLException {
+		final Connection connection = DriverManager.getConnection( envionment.getUrl(), envionment.getUser(), envionment.getPass() );
+		final LobCreationContext lobCreationContext = new LobCreationContext() {
+			public Object execute(Callback callback) {
+				try {
+					return callback.executeOnConnection( connection );
+				}
+				catch ( SQLException e ) {
+					throw new RuntimeException( "Unexpected sql exception", e );
+				}
+			}
+		};
+
+		LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( connection ).getLobCreator( lobCreationContext );
+		envionment.verifyCreator( lobCreator );
+
+		Blob blob = lobCreator.createBlob( new byte[] {} );
+		envionment.verifyBlob( blob );
+		blob = lobCreator.wrap( blob );
+		assertTrue( blob instanceof WrappedBlob );
+
+		Clob clob = lobCreator.createClob( "Hi" );
+		envionment.verifyClob( clob );
+		clob = lobCreator.wrap( clob );
+		assertTrue( clob instanceof WrappedClob );
+
+		Clob nclob = lobCreator.createNClob( "Hi" );
+		envionment.verifyNClob( nclob );
+		assertTrue( NClob.class.isInstance( nclob ) );
+		nclob = lobCreator.wrap( nclob );
+		assertTrue( nclob instanceof WrappedClob );
+
+		blob.free();
+		clob.free();
+		nclob.free();
+		connection.close();
+	}
+
+	public void testLegacyLobCreator() throws SQLException {
+		LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( null ).getLobCreator();
+
+		Blob blob = lobCreator.createBlob( new byte[] {} );
+		assertTrue( blob instanceof BlobImplementer );
+		blob = lobCreator.wrap( blob );
+		assertTrue( blob instanceof WrappedBlob );
+
+		Clob clob = lobCreator.createClob( "Hi" );
+		assertTrue( clob instanceof ClobImplementer );
+		clob = lobCreator.wrap( clob );
+		assertTrue( clob instanceof WrappedClob );
+
+		Clob nclob = lobCreator.createNClob( "Hi" );
+		assertTrue( nclob instanceof NClobImplementer );
+		assertTrue( NClob.class.isInstance( nclob ) );
+		nclob = lobCreator.wrap( nclob );
+		assertTrue( nclob instanceof WrappedClob );
+
+		blob.free();
+		clob.free();
+		nclob.free();
+	}
+}

Added: core/trunk/jdbc4-testing/src/test/resources/log4j.properties
===================================================================
--- core/trunk/jdbc4-testing/src/test/resources/log4j.properties	                        (rev 0)
+++ core/trunk/jdbc4-testing/src/test/resources/log4j.properties	2009-10-15 16:26:26 UTC (rev 17767)
@@ -0,0 +1,7 @@
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+
+log4j.rootLogger=info, stdout

Modified: core/trunk/parent/pom.xml
===================================================================
--- core/trunk/parent/pom.xml	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/parent/pom.xml	2009-10-15 16:26:26 UTC (rev 17767)
@@ -118,10 +118,6 @@
                 <extensions>true</extensions>
             </plugin>
             <plugin>
-                <!-- require at least JDK 1.5 to run the build -->
-                <!-- ... -->
-                <!-- we need at least Maven 2.0.8 because of a bug fix affecting our antlr usage -->
-                <!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-enforcer-plugin</artifactId>
                 <executions>
@@ -135,9 +131,12 @@
                 <configuration>
                     <rules>
                         <requireJavaVersion>
-                            <version>[1.5,)</version>
+                            <!-- require JDK 1.5 to run the build -->
+                            <version>[1.5,1.6)</version>
                         </requireJavaVersion>
                         <requireMavenVersion>
+                            <!-- we need at least Maven 2.0.8 because of a bug fix affecting our antlr usage -->
+                            <!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
                             <version>(2.0.7,)</version>
                         </requireMavenVersion>
                     </rules>

Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml	2009-10-15 15:28:29 UTC (rev 17766)
+++ core/trunk/pom.xml	2009-10-15 16:26:26 UTC (rev 17767)
@@ -32,9 +32,10 @@
         <module>jmx</module>
         <module>testing</module>
         <module>testsuite</module>
+        <module>jdbc3-testing</module>
+        <module>jdbc4-testing</module>
         <module>tutorials</module>
-        <module>hibernate-maven-plugin</module>
-        <!--
+<!--
     Need to scope bytecode providers first...
         <module>bytecode-cglib</module>
         <module>bytecode-javassist</module>



More information about the hibernate-commits mailing list