Author: stliu
Date: 2010-04-27 03:17:09 -0400 (Tue, 27 Apr 2010)
New Revision: 19300
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties
Removed:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/lob/
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java
Log:
JBPAPP-4180 HHH-2412 Support for JDBC4
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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;
@@ -387,57 +389,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.
*
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -33,6 +33,7 @@
import org.hibernate.cache.RegionFactory;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.jdbc.JdbcSupport;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.hql.QueryTranslatorFactory;
import org.hibernate.jdbc.BatcherFactory;
@@ -96,7 +97,7 @@
private EntityTuplizerFactory entityTuplizerFactory;
// private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and
HHH-1907
// private BytecodeProvider bytecodeProvider;
-
+ private JdbcSupport jdbcSupport;
/**
* Package protected constructor
*/
@@ -297,7 +298,9 @@
// return componentTuplizerFactory;
// }
-
+ public JdbcSupport getJdbcSupport(){
+ return jdbcSupport;
+ }
// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// void setShowSqlEnabled(boolean b) {
@@ -492,7 +495,9 @@
// this.componentTuplizerFactory = componentTuplizerFactory;
// }
-
+ void setJdbcSupport(JdbcSupport jdbcSupport){
+ this.jdbcSupport = jdbcSupport;
+ }
// public BytecodeProvider getBytecodeProvider() {
// return bytecodeProvider;
// }
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -47,6 +47,8 @@
import org.hibernate.connection.ConnectionProviderFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.resolver.DialectFactory;
+import org.hibernate.engine.jdbc.JdbcSupport;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.exception.SQLExceptionConverterFactory;
import org.hibernate.hql.QueryTranslatorFactory;
@@ -97,7 +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
// not defined as an Environment constant...
@@ -115,7 +117,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();
metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
@@ -145,7 +147,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();
properties.putAll( dialect.getDefaultProperties() );
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,163 @@
+/*
+ * 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;
+ }
+ if ( "toString".equals( method.getName() ) ) {
+ return this.toString();
+ }
+ if ( "equals".equals( method.getName() ) ) {
+ return Boolean.valueOf( proxy == args[0] );
+ }
+ if ( "hashCode".equals( method.getName() ) ) {
+ return new Integer( this.hashCode() );
+ }
+ 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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,177 @@
+/*
+ * 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;
+ }
+ if ( "toString".equals( method.getName() ) ) {
+ return this.toString();
+ }
+ if ( "equals".equals( method.getName() ) ) {
+ return Boolean.valueOf( proxy == args[0] );
+ }
+ if ( "hashCode".equals( method.getName() ) ) {
+ return new Integer( this.hashCode() );
+ }
+ 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;
+ }
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,238 @@
+/*
+ * 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;
+import org.hibernate.JDBCException;
+
+/**
+ * {@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 JDBCException( "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 JDBCException( "Unable to prepare BLOB binary stream for
writing",e );
+ }
+ catch ( IOException e ) {
+ throw new HibernateException( "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 JDBCException( "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 JDBCException( "Unable to prepare CLOB stream for writing", e );
+ }
+ catch ( IOException e ) {
+ throw new HibernateException( "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 JDBCException( "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 JDBCException( "Unable to prepare NCLOB stream for writing", e );
+ }
+ catch ( IOException e ) {
+ throw new HibernateException( "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." );
+ }
+ catch ( IllegalAccessException e ) {
+ // this again is a big big error...
+ throw new IllegalStateException( "Illegal access attempt on JDBC method " +
creationMethod.getName() );
+ }
+ }
+ }
+
+ 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);
+ }
+ }
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+/**
+ * Isolates Hibernate interactions with JDBC in terms of variations between JDBC 3 (JDK
1.4 and 1.5)
+ * and JDBC 4 (JDK 1.6).
+ *
+ * @author Steve Ebersole
+ */
+public interface JdbcSupport {
+ /**
+ * Creates an instance of a {@link LobCreator} that does not use the underlying JDBC
{@link java.sql.Connection}
+ * to create LOBs.
+ * <p/>
+ * This method is here solely to support the older, now-deprecated method of creating
LOBs via
+ * the various {@link org.hibernate.Hibernate#createBlob} and {@link
org.hibernate.Hibernate#createClob} methods on
+ * {@link org.hibernate.Hibernate}.
+ *
+ * @return The LOB creator.
+ * @deprecated Use {@link #getLobCreator(LobCreationContext)} instead.
+ */
+ public LobCreator getLobCreator();
+
+ /**
+ * Create an instance of a {@link LobCreator} appropriate for the current envionment,
mainly meant to account for
+ * variance between JDBC 4 (<= JDK 1.6) and JDBC3 (>= JDK 1.5).
+ *
+ * @param lobCreationContext The context in which the LOB is being created
+ * @return The LOB creator.
+ */
+ public LobCreator getLobCreator(LobCreationContext lobCreationContext);
+
+ /**
+ * Wrap the given {@link ResultSet} in one that caches the column-name ->
column-index resolution.
+ *
+ * @param resultSet The {@link ResultSet} to wrap.
+ * @param columnNameCache The resolution cache.
+ * @return The wrapper.
+ */
+ public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache);
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,117 @@
+/*
+ * 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 java.sql.DatabaseMetaData;
+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 ) {
+ log.info( "Disabling contextual LOB creation as connection was null" );
+ return false;
+ }
+
+ try {
+ try {
+ DatabaseMetaData meta = jdbcConnection.getMetaData();
+ // if the jdbc driver version is less than 4, it shouldn't have createClob
+ if ( meta.getJDBCMajorVersion() < 4 ) {
+ log.info(
+ "Disabling contextual LOB creation as JDBC driver reported JDBC version
[" +
+ meta.getJDBCMajorVersion() + "] less than 4"
+ );
+ return false;
+ }
+ }
+ catch ( SQLException ignore ) {
+ // ignore exception and continue
+ }
+
+ 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( "Disabling contextual LOB creation as createClob() method threw error
: " + t );
+ }
+ }
+ }
+ catch ( NoSuchMethodException ignore ) {
+ }
+
+ return false;
+ }
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+/**
+ * Contract for creating various LOB references.
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public interface LobCreator {
+ /**
+ * Wrap the given blob in a serializable wrapper.
+ *
+ * @param blob The blob to be wrapped.
+ * @return The wrapped blob which will be castable to {@link Blob} as well as {@link
WrappedBlob}.
+ */
+ public Blob wrap(Blob blob);
+
+ /**
+ * Wrap the given clob in a serializable wrapper.
+ *
+ * @param clob The clob to be wrapped.
+ * @return The wrapped clob which will be castable to {@link Clob} as well as {@link
WrappedClob}.
+ */
+ public Clob wrap(Clob clob);
+
+ /**
+ * Create a BLOB reference encapsulating the given byte array.
+ *
+ * @param bytes The byte array to wrap as a blob.
+ * @return The created blob, castable to {@link Blob} as well as {@link
BlobImplementer}
+ */
+ public Blob createBlob(byte[] bytes);
+
+ /**
+ * Create a BLOB reference encapsulating the given binary stream.
+ *
+ * @param stream The binary stream to wrap as a blob.
+ * @param length The length of the stream.
+ * @return The created blob, castable to {@link Blob} as well as {@link
BlobImplementer}
+ */
+ public Blob createBlob(InputStream stream, long length);
+
+ /**
+ * Create a CLOB reference encapsulating the given String data.
+ *
+ * @param string The String to wrap as a clob.
+ * @return The created clob, castable to {@link Clob} as well as {@link
ClobImplementer}
+ */
+ public Clob createClob(String string);
+
+ /**
+ * Create a CLOB reference encapsulating the given character data.
+ *
+ * @param reader The character data reader.
+ * @param length The length of the reader data.
+ * @return The created clob, castable to {@link Clob} as well as {@link
ClobImplementer}
+ */
+ public Clob createClob(Reader reader, long length);
+
+ /**
+ * Create a NCLOB reference encapsulating the given String data.
+ *
+ * @param string The String to wrap as a NCLOB.
+ * @return The created NCLOB, castable as {@link Clob} as well as {@link
NClobImplementer}. In JDK 1.6
+ * environments, also castable to java.sql.NClob
+ */
+ public Clob createNClob(String string);
+
+ /**
+ * Create a NCLOB reference encapsulating the given character data.
+ *
+ * @param reader The character data reader.
+ * @param length The length of the reader data.
+ * @return The created NCLOB, castable as {@link Clob} as well as {@link
NClobImplementer}. In JDK 1.6
+ * environments, also castable to java.sql.NClob
+ */
+ public Clob createNClob(Reader reader, long length);
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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 extends ClobImplementer {
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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 );
+ }
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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();
+ }
+
+}
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -76,6 +76,8 @@
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.StatefulPersistenceContext;
import org.hibernate.engine.Status;
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreationContext.Callback;
import org.hibernate.engine.query.FilterQueryPlan;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan;
@@ -139,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...
@@ -1979,7 +1981,22 @@
oos.writeObject( enabledFilters );
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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -63,6 +63,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 +71,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 +1838,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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java 2010-04-27
07:07:12 UTC (rev 19299)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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 {
Added: core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml (rev
0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml 2010-04-27 07:17:09 UTC (rev
19300)
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.3.2.GA_CP01</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>hibernate-jdbc3-testing</artifactId>
+ <packaging>jar</packaging>
+
+ <name>Hibernate 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>
+ </dependencies>
+
+</project>
Added:
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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
Added: core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml (rev
0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml 2010-04-27 07:17:09 UTC (rev
19300)
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.3.2.GA_CP01</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>hibernate-jdbc4-testing</artifactId>
+ <name>Hibernate 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>
+ <compilerVersion>1.6</compilerVersion>
+ <executable>${jdk16_home}/bin/javac</executable>
+ <fork>true</fork>
+ <verbose>true</verbose>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <jvm>${jdk16_home}/bin/java</jvm>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added:
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java 2010-04-27
07:17:09 UTC (rev 19300)
@@ -0,0 +1,347 @@
+/*
+ * 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.*;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+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 {
+ public void testConnectedLobCreator() throws SQLException {
+ final Connection connection = createConnectionProxy(
+ 4,
+ new JdbcLobBuilder() {
+ public Blob createBlob() {
+ return new JdbcBlob();
+ }
+
+ public Clob createClob() {
+ return new JdbcClob();
+ }
+
+ public NClob createNClob() {
+ return new JdbcNClob();
+ }
+ }
+ );
+ final LobCreationContext lobCreationContext = new LobCreationContext() {
+ public Object execute(Callback callback) {
+ try {
+ return callback.executeOnConnection( connection );
+ }
+ catch ( SQLException e ) {
+ throw new RuntimeException( "Unexpected SQLException", e );
+ }
+ }
+ };
+
+ LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( connection ).getLobCreator(
lobCreationContext );
+ assertTrue( lobCreator instanceof ContextualLobCreator );
+
+ Blob blob = lobCreator.createBlob( new byte[] {} );
+ assertTrue( blob instanceof JdbcBlob );
+ blob = lobCreator.wrap( blob );
+ assertTrue( blob instanceof WrappedBlob );
+
+ Clob clob = lobCreator.createClob( "Hi" );
+ assertTrue( clob instanceof JdbcClob );
+ clob = lobCreator.wrap( clob );
+ assertTrue( clob instanceof WrappedClob );
+
+ Clob nclob = lobCreator.createNClob( "Hi" );
+ assertTrue( nclob instanceof JdbcNClob );
+ nclob = lobCreator.wrap( nclob );
+ assertTrue( nclob instanceof WrappedClob );
+
+ blob.free();
+ clob.free();
+ nclob.free();
+ connection.close();
+ }
+
+ public void testConnectedLobCreatorWithUnSupportedCreations() throws SQLException {
+ final Connection connection = createConnectionProxy(
+ 3,
+ new JdbcLobBuilder() {
+ public Blob createBlob() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Clob createClob() {
+ throw new UnsupportedOperationException();
+ }
+
+ public NClob createNClob() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ );
+ final LobCreationContext lobCreationContext = new LobCreationContext() {
+ public Object execute(Callback callback) {
+ try {
+ return callback.executeOnConnection( connection );
+ }
+ catch ( SQLException e ) {
+ throw new RuntimeException( "Unexpected SQLException", e );
+ }
+ }
+ };
+
+ LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( connection ).getLobCreator(
lobCreationContext );
+ assertTrue( lobCreator instanceof NonContextualLobCreator );
+
+ 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 ClobImplementer );
+ assertTrue( nclob instanceof NClobImplementer );
+ 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();
+ }
+
+ private interface JdbcLobBuilder {
+ public Blob createBlob();
+ public Clob createClob();
+ public NClob createNClob();
+ }
+
+ private class ConnectionProxyHandler implements InvocationHandler {
+ private final JdbcLobBuilder lobBuilder;
+ private final DatabaseMetaData metadata;
+
+ private ConnectionProxyHandler(int version, JdbcLobBuilder lobBuilder) {
+ this.lobBuilder = lobBuilder;
+ this.metadata = createMetadataProxy( version );
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ // the only methods we are interested in are the LOB creation methods...
+ if ( args == null || args.length == 0 ) {
+ final String methodName = method.getName();
+ if ( "createBlob".equals( methodName ) ) {
+ return lobBuilder.createBlob();
+ }
+ else if ( "createClob".equals( methodName ) ) {
+ return lobBuilder.createClob();
+ }
+ else if ( "createNClob".equals( methodName ) ) {
+ return lobBuilder.createNClob();
+ }
+ else if ( "getMetaData".equals( methodName ) ) {
+ return metadata;
+ }
+ }
+ return null;
+ }
+ }
+
+ private static Class[] CONN_PROXY_TYPES = new Class[] { Connection.class };
+
+ private Connection createConnectionProxy(int version, JdbcLobBuilder jdbcLobBuilder) {
+ ConnectionProxyHandler handler = new ConnectionProxyHandler( version, jdbcLobBuilder
);
+ return ( Connection ) Proxy.newProxyInstance( getClass().getClassLoader(),
CONN_PROXY_TYPES, handler );
+ }
+
+ private class MetadataProxyHandler implements InvocationHandler {
+ private final int jdbcVersion;
+
+ private MetadataProxyHandler(int jdbcVersion) {
+ this.jdbcVersion = jdbcVersion;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ( "getJDBCMajorVersion".equals( methodName ) ) {
+ return jdbcVersion;
+ }
+ return null;
+ }
+ }
+
+ private static Class[] META_PROXY_TYPES = new Class[] { DatabaseMetaData.class };
+
+ private DatabaseMetaData createMetadataProxy(int version) {
+ MetadataProxyHandler handler = new MetadataProxyHandler( version );
+ return ( DatabaseMetaData ) Proxy.newProxyInstance( getClass().getClassLoader(),
META_PROXY_TYPES, handler );
+ }
+
+ private class JdbcBlob implements Blob {
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ public byte[] getBytes(long pos, int length) throws SQLException {
+ return new byte[0];
+ }
+
+ public InputStream getBinaryStream() throws SQLException {
+ return null;
+ }
+
+ public long position(byte[] pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ public long position(Blob pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ public int setBytes(long pos, byte[] bytes) throws SQLException {
+ return 0;
+ }
+
+ public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ public OutputStream setBinaryStream(long pos) throws SQLException {
+ return null;
+ }
+
+ public void truncate(long len) throws SQLException {
+ }
+
+ public void free() throws SQLException {
+ }
+
+ public InputStream getBinaryStream(long pos, long length) throws SQLException {
+ return null;
+ }
+ }
+
+ private class JdbcClob implements Clob {
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ public String getSubString(long pos, int length) throws SQLException {
+ return null;
+ }
+
+ public Reader getCharacterStream() throws SQLException {
+ return null;
+ }
+
+ public InputStream getAsciiStream() throws SQLException {
+ return null;
+ }
+
+ public long position(String searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ public long position(Clob searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ public int setString(long pos, String str) throws SQLException {
+ return 0;
+ }
+
+ public int setString(long pos, String str, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ public OutputStream setAsciiStream(long pos) throws SQLException {
+ return null;
+ }
+
+ public Writer setCharacterStream(long pos) throws SQLException {
+ return null;
+ }
+
+ public void truncate(long len) throws SQLException {
+ }
+
+ public void free() throws SQLException {
+ }
+
+ public Reader getCharacterStream(long pos, long length) throws SQLException {
+ return null;
+ }
+ }
+
+ private class JdbcNClob extends JdbcClob implements NClob {
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties
(rev 0)
+++
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties 2010-04-27
07:17:09 UTC (rev 19300)
@@ -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