HHH-2412 - Support for JDBC4
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17767 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
a000137e19
commit
36dbd3a06e
|
@ -34,11 +34,10 @@ import java.util.Map;
|
|||
import org.dom4j.Node;
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.engine.Mapping;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.lob.BlobImpl;
|
||||
import org.hibernate.util.ArrayHelper;
|
||||
|
||||
/**
|
||||
|
@ -51,9 +50,10 @@ import org.hibernate.util.ArrayHelper;
|
|||
*/
|
||||
@Deprecated
|
||||
public class ByteArrayBlobType extends AbstractLobType {
|
||||
private static final int[] TYPES = new int[] { Types.BLOB };
|
||||
|
||||
public int[] sqlTypes(Mapping mapping) throws MappingException {
|
||||
return new int[]{Types.BLOB};
|
||||
public int[] sqlTypes(Mapping mapping) {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -128,7 +128,7 @@ public class ByteArrayBlobType extends AbstractLobType {
|
|||
st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
|
||||
}
|
||||
else {
|
||||
st.setBlob( index, new BlobImpl( toSet ) );
|
||||
st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@ import org.dom4j.Node;
|
|||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.engine.Mapping;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.lob.BlobImpl;
|
||||
import org.hibernate.usertype.ParameterizedType;
|
||||
import org.hibernate.util.ReflectHelper;
|
||||
import org.hibernate.util.SerializationHelper;
|
||||
|
@ -99,7 +99,7 @@ public class SerializableToBlobType extends AbstractLobType implements Parameter
|
|||
st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
|
||||
}
|
||||
else {
|
||||
st.setBlob( index, new BlobImpl( toSet ) );
|
||||
st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.io.IOException;
|
|||
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 java.util.Properties;
|
|||
|
||||
import org.hibernate.collection.PersistentCollection;
|
||||
import org.hibernate.engine.HibernateIterator;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.jdbc.NonContextualLobCreator;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.StreamUtils;
|
||||
import org.hibernate.intercept.FieldInterceptionHelper;
|
||||
import org.hibernate.intercept.FieldInterceptor;
|
||||
import org.hibernate.lob.BlobImpl;
|
||||
import org.hibernate.lob.ClobImpl;
|
||||
import org.hibernate.lob.SerializableBlob;
|
||||
import org.hibernate.lob.SerializableClob;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.type.AnyType;
|
||||
|
@ -386,54 +388,163 @@ public final class Hibernate {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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
|
||||
* @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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,8 +571,7 @@ public final class Hibernate {
|
|||
*
|
||||
* @param proxy The potential proxy
|
||||
* @param propertyName the name of a persistent attribute of the object
|
||||
* @return true if the named property of the object is not listed as uninitialized
|
||||
* @return false if the object is an uninitialized proxy, or the named property is uninitialized
|
||||
* @return true if the named property of the object is not listed as uninitialized; false otherwise
|
||||
*/
|
||||
public static boolean isPropertyInitialized(Object proxy, String propertyName) {
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.engine.jdbc.JdbcSupport;
|
||||
import org.hibernate.tuple.entity.EntityTuplizerFactory;
|
||||
import org.hibernate.tuple.component.ComponentTuplizerFactory;
|
||||
import org.hibernate.cache.QueryCacheFactory;
|
||||
|
@ -98,6 +99,7 @@ public final class Settings {
|
|||
private boolean checkNullability;
|
||||
// private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907
|
||||
// private BytecodeProvider bytecodeProvider;
|
||||
private JdbcSupport jdbcSupport;
|
||||
|
||||
/**
|
||||
* Package protected constructor
|
||||
|
@ -299,8 +301,12 @@ public final class Settings {
|
|||
// return componentTuplizerFactory;
|
||||
// }
|
||||
|
||||
public JdbcSupport getJdbcSupport() {
|
||||
return jdbcSupport;
|
||||
}
|
||||
|
||||
// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// void setShowSqlEnabled(boolean b) {
|
||||
// showSql = b;
|
||||
|
@ -502,8 +508,11 @@ public final class Settings {
|
|||
// this.componentTuplizerFactory = componentTuplizerFactory;
|
||||
// }
|
||||
|
||||
void setJdbcSupport(JdbcSupport jdbcSupport) {
|
||||
this.jdbcSupport = jdbcSupport;
|
||||
}
|
||||
|
||||
// public BytecodeProvider getBytecodeProvider() {
|
||||
// public BytecodeProvider getBytecodeProvider() {
|
||||
// return bytecodeProvider;
|
||||
// }
|
||||
//
|
||||
|
|
|
@ -38,6 +38,8 @@ import org.slf4j.LoggerFactory;
|
|||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.JdbcSupport;
|
||||
import org.hibernate.engine.jdbc.JdbcSupportLoader;
|
||||
import org.hibernate.bytecode.BytecodeProvider;
|
||||
import org.hibernate.cache.QueryCacheFactory;
|
||||
import org.hibernate.cache.RegionFactory;
|
||||
|
@ -97,6 +99,7 @@ public class SettingsFactory implements Serializable {
|
|||
boolean metaReportsDDLCausesTxnCommit = false;
|
||||
boolean metaReportsDDLInTxnSupported = true;
|
||||
Dialect dialect = null;
|
||||
JdbcSupport jdbcSupport = null;
|
||||
|
||||
// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
|
||||
// The need for it is intended to be alleviated with future developement, thus it is
|
||||
|
@ -115,6 +118,7 @@ public class SettingsFactory implements Serializable {
|
|||
log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
|
||||
|
||||
dialect = DialectFactory.buildDialect( props, conn );
|
||||
jdbcSupport = JdbcSupportLoader.loadJdbcSupport( conn );
|
||||
|
||||
metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
|
||||
metaSupportsBatchUpdates = meta.supportsBatchUpdates();
|
||||
|
@ -145,6 +149,10 @@ public class SettingsFactory implements Serializable {
|
|||
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();
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Blob;
|
||||
import java.sql.SQLException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Manages aspects of proxying {@link Blob Blobs} for non-contextual creation, including proxy creation and
|
||||
* handling proxy invocations.
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class BlobProxy implements InvocationHandler {
|
||||
private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, BlobImplementer.class };
|
||||
|
||||
private InputStream stream;
|
||||
private long length;
|
||||
private boolean needsReset = false;
|
||||
|
||||
/**
|
||||
* Ctor used to build {@link Blob} from byte array.
|
||||
*
|
||||
* @param bytes The byte array
|
||||
* @see #generateProxy(byte[])
|
||||
*/
|
||||
private BlobProxy(byte[] bytes) {
|
||||
this.stream = new ByteArrayInputStream( bytes );
|
||||
this.length = bytes.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ctor used to build {@link Blob} from a stream.
|
||||
*
|
||||
* @param stream The binary stream
|
||||
* @param length The length of the stream
|
||||
* @see #generateProxy(java.io.InputStream, long)
|
||||
*/
|
||||
private BlobProxy(InputStream stream, long length) {
|
||||
this.stream = stream;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
private long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
private InputStream getStream() throws SQLException {
|
||||
try {
|
||||
if (needsReset) {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
catch ( IOException ioe) {
|
||||
throw new SQLException("could not reset reader");
|
||||
}
|
||||
needsReset = true;
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws UnsupportedOperationException if any methods other than {@link Blob#length()}
|
||||
* or {@link Blob#getBinaryStream} are invoked.
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if ( "length".equals( method.getName() ) ) {
|
||||
return new Long( getLength() );
|
||||
}
|
||||
if ( "getBinaryStream".equals( method.getName() ) && method.getParameterTypes().length == 0 ) {
|
||||
return getStream();
|
||||
}
|
||||
if ( "free".equals( method.getName() ) ) {
|
||||
stream.close();
|
||||
return null;
|
||||
}
|
||||
throw new UnsupportedOperationException( "Blob may not be manipulated from creating session" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a BlobImpl proxy using byte data.
|
||||
*
|
||||
* @param bytes The data to be created as a Blob.
|
||||
*
|
||||
* @return The generated proxy.
|
||||
*/
|
||||
public static Blob generateProxy(byte[] bytes) {
|
||||
return ( Blob ) Proxy.newProxyInstance(
|
||||
getProxyClassLoader(),
|
||||
PROXY_INTERFACES,
|
||||
new BlobProxy( bytes )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a BlobImpl proxy using a given number of bytes from an InputStream.
|
||||
*
|
||||
* @param stream The input stream of bytes to be created as a Blob.
|
||||
* @param length The number of bytes from stream to be written to the Blob.
|
||||
*
|
||||
* @return The generated proxy.
|
||||
*/
|
||||
public static Blob generateProxy(InputStream stream, long length) {
|
||||
return ( Blob ) Proxy.newProxyInstance(
|
||||
getProxyClassLoader(),
|
||||
PROXY_INTERFACES,
|
||||
new BlobProxy( stream, length )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the appropriate class loader to which the generated proxy
|
||||
* should be scoped.
|
||||
*
|
||||
* @return The class loader appropriate for proxy construction.
|
||||
*/
|
||||
private static ClassLoader getProxyClassLoader() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if ( cl == null ) {
|
||||
cl = BlobImplementer.class.getClassLoader();
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Manages aspects of proxying {@link Clob Clobs} for non-contextual creation, including proxy creation and
|
||||
* handling proxy invocations.
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class ClobProxy implements InvocationHandler {
|
||||
private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, ClobImplementer.class };
|
||||
|
||||
private Reader reader;
|
||||
private long length;
|
||||
private boolean needsReset = false;
|
||||
|
||||
|
||||
/**
|
||||
* Ctor used to build {@link Clob} from string data.
|
||||
*
|
||||
* @param string The byte array
|
||||
* @see #generateProxy(String)
|
||||
*/
|
||||
protected ClobProxy(String string) {
|
||||
reader = new StringReader(string);
|
||||
length = string.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ctor used to build {@link Clob} from a reader.
|
||||
*
|
||||
* @param reader The character reader.
|
||||
* @param length The length of the reader stream.
|
||||
* @see #generateProxy(java.io.Reader, long)
|
||||
*/
|
||||
protected ClobProxy(Reader reader, long length) {
|
||||
this.reader = reader;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
protected long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
protected InputStream getAsciiStream() throws SQLException {
|
||||
resetIfNeeded();
|
||||
return new ReaderInputStream( reader );
|
||||
}
|
||||
|
||||
protected Reader getCharacterStream() throws SQLException {
|
||||
resetIfNeeded();
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws UnsupportedOperationException if any methods other than {@link Clob#length()},
|
||||
* {@link Clob#getAsciiStream()}, or {@link Clob#getCharacterStream()} are invoked.
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if ( "length".equals( method.getName() ) ) {
|
||||
return new Long( getLength() );
|
||||
}
|
||||
if ( "getAsciiStream".equals( method.getName() ) ) {
|
||||
return getAsciiStream();
|
||||
}
|
||||
if ( "getCharacterStream".equals( method.getName() ) ) {
|
||||
return getCharacterStream();
|
||||
}
|
||||
if ( "free".equals( method.getName() ) ) {
|
||||
reader.close();
|
||||
return null;
|
||||
}
|
||||
throw new UnsupportedOperationException( "Clob may not be manipulated from creating session" );
|
||||
}
|
||||
|
||||
protected void resetIfNeeded() throws SQLException {
|
||||
try {
|
||||
if ( needsReset ) {
|
||||
reader.reset();
|
||||
}
|
||||
}
|
||||
catch ( IOException ioe ) {
|
||||
throw new SQLException( "could not reset reader" );
|
||||
}
|
||||
needsReset = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@link Clob} proxy using the string data.
|
||||
*
|
||||
* @param string The data to be wrapped as a {@link Clob}.
|
||||
*
|
||||
* @return The generated proxy.
|
||||
*/
|
||||
public static Clob generateProxy(String string) {
|
||||
return ( Clob ) Proxy.newProxyInstance(
|
||||
getProxyClassLoader(),
|
||||
PROXY_INTERFACES,
|
||||
new ClobProxy( string )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@link Clob} proxy using a character reader of given length.
|
||||
*
|
||||
* @param reader The character reader
|
||||
* @param length The length of the character reader
|
||||
*
|
||||
* @return The generated proxy.
|
||||
*/
|
||||
public static Clob generateProxy(Reader reader, long length) {
|
||||
return ( Clob ) Proxy.newProxyInstance(
|
||||
getProxyClassLoader(),
|
||||
PROXY_INTERFACES,
|
||||
new ClobProxy( reader, length )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the appropriate class loader to which the generated proxy
|
||||
* should be scoped.
|
||||
*
|
||||
* @return The class loader appropriate for proxy construction.
|
||||
*/
|
||||
protected static ClassLoader getProxyClassLoader() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if ( cl == null ) {
|
||||
cl = ClobImplementer.class.getClassLoader();
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
}
|
|
@ -20,35 +20,36 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.jdbc;
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementation of ColumnNameCache.
|
||||
* 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 );
|
||||
this.columnNameToIndexCache = new HashMap( columnCount + (int)( columnCount * LOAD_FACTOR ) + 1, LOAD_FACTOR );
|
||||
}
|
||||
|
||||
public int getIndexForColumnName(String columnName, ResultSetWrapper rs)throws SQLException {
|
||||
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.getTarget().findColumn( columnName );
|
||||
int index = rs.findColumn( columnName );
|
||||
columnNameToIndexCache.put( columnName, new Integer(index) );
|
||||
return index;
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.sql.Blob;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Clob;
|
||||
import java.sql.Connection;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* {@link LobCreator} implementation using contextual creation against the JDBC {@link java.sql.Connection} class's LOB creation
|
||||
* methods.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class ContextualLobCreator extends AbstractLobCreator implements LobCreator {
|
||||
private LobCreationContext lobCreationContext;
|
||||
|
||||
public ContextualLobCreator(LobCreationContext lobCreationContext) {
|
||||
this.lobCreationContext = lobCreationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the basic contextual BLOB reference.
|
||||
*
|
||||
* @return The created BLOB reference.
|
||||
*/
|
||||
public Blob createBlob() {
|
||||
return ( Blob ) lobCreationContext.execute( CREATE_BLOB_CALLBACK );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Blob createBlob(byte[] bytes) {
|
||||
try {
|
||||
Blob blob = createBlob();
|
||||
blob.setBytes( 1, bytes );
|
||||
return blob;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new IllegalStateException( "Unable to set BLOB bytes after creation", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Blob createBlob(InputStream inputStream, long length) {
|
||||
try {
|
||||
Blob blob = createBlob();
|
||||
OutputStream byteStream = blob.setBinaryStream( 1 );
|
||||
StreamUtils.copy( inputStream, byteStream );
|
||||
byteStream.flush();
|
||||
byteStream.close();
|
||||
// todo : validate length written versus length given?
|
||||
return blob;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new IllegalStateException( "Unable to prepare BLOB binary stream for writing", e );
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new IllegalStateException( "Unable to write stream contents to BLOB", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the basic contextual CLOB reference.
|
||||
*
|
||||
* @return The created CLOB reference.
|
||||
*/
|
||||
public Clob createClob() {
|
||||
return ( Clob ) lobCreationContext.execute( CREATE_CLOB_CALLBACK );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Clob createClob(String string) {
|
||||
try {
|
||||
Clob clob = createClob();
|
||||
clob.setString( 1, string );
|
||||
return clob;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new IllegalStateException( "Unable to set CLOB string after creation", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Clob createClob(Reader reader, long length) {
|
||||
try {
|
||||
Clob clob = createClob();
|
||||
Writer writer = clob.setCharacterStream( 1 );
|
||||
StreamUtils.copy( reader, writer );
|
||||
writer.flush();
|
||||
writer.close();
|
||||
return clob;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new IllegalStateException( "Unable to prepare CLOB stream for writing", e );
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new IllegalStateException( "Unable to write CLOB stream content", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the basic contextual NCLOB reference.
|
||||
*
|
||||
* @return The created NCLOB reference.
|
||||
*/
|
||||
public Clob createNClob() {
|
||||
return ( Clob ) lobCreationContext.execute( CREATE_NCLOB_CALLBACK );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Clob createNClob(String string) {
|
||||
try {
|
||||
Clob clob = createNClob();
|
||||
clob.setString( 1, string );
|
||||
return clob;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new IllegalStateException( "Unable to set NCLOB string after creation", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Clob createNClob(Reader reader, long length) {
|
||||
try {
|
||||
Clob clob = createNClob();
|
||||
Writer writer = clob.setCharacterStream( 1 );
|
||||
StreamUtils.copy( reader, writer );
|
||||
writer.flush();
|
||||
writer.close();
|
||||
return clob;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new IllegalStateException( "Unable to prepare NCLOB stream for writing", e );
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new IllegalStateException( "Unable to write NCLOB stream content", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final Class[] CREATION_METHOD_SIG = new Class[0];
|
||||
private static final Object[] CREATION_METHOD_ARGS = new Object[0];
|
||||
|
||||
private static final LobCreationContext.Callback CREATE_BLOB_CALLBACK;
|
||||
private static final LobCreationContext.Callback CREATE_CLOB_CALLBACK;
|
||||
private static final LobCreationContext.Callback CREATE_NCLOB_CALLBACK;
|
||||
|
||||
static {
|
||||
CREATE_BLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createBlob" ) );
|
||||
CREATE_CLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createClob" ) );
|
||||
CREATE_NCLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createNClob" ) );
|
||||
}
|
||||
|
||||
private static class CallbackImpl implements LobCreationContext.Callback {
|
||||
private final Method creationMethod;
|
||||
|
||||
private CallbackImpl(Method creationMethod) {
|
||||
this.creationMethod = creationMethod;
|
||||
}
|
||||
|
||||
public Object executeOnConnection(Connection connection) throws SQLException {
|
||||
try {
|
||||
return creationMethod.invoke( connection, CREATION_METHOD_ARGS );
|
||||
}
|
||||
catch ( InvocationTargetException e ) {
|
||||
if ( e.getTargetException() instanceof SQLException ) {
|
||||
throw ( SQLException ) e.getTargetException();
|
||||
}
|
||||
else {
|
||||
throw new HibernateException( "Exception invoking " + creationMethod.getName(), e.getTargetException() );
|
||||
}
|
||||
}
|
||||
catch ( AbstractMethodError e ) {
|
||||
// this again is a big big error...
|
||||
throw new IllegalStateException( "Useable implementation of " + creationMethod.getName() + " not found.", e );
|
||||
}
|
||||
catch ( IllegalAccessException e ) {
|
||||
// this again is a big big error...
|
||||
throw new IllegalStateException( "Illegal access attempt on JDBC method " + creationMethod.getName(), e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getConnectionlobCreationMethod(String methodName) {
|
||||
try {
|
||||
return Connection.class.getMethod( methodName, CREATION_METHOD_SIG );
|
||||
}
|
||||
catch ( NoSuchMethodException e ) {
|
||||
// this is a big big error if we get here and these methods are not part of the Connection interface...
|
||||
throw new IllegalStateException( "JDBC driver did not implement " + methodName, e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Builds {@link JdbcSupport} instances based on the capabilities of the environment.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcSupportLoader {
|
||||
private static final Logger log = LoggerFactory.getLogger( JdbcSupportLoader.class );
|
||||
|
||||
/**
|
||||
* The public factory method for obtaining the appropriate (accoring to given JDBC {@link java.sql.Connection})
|
||||
* {@link JdbcSupport}.
|
||||
*
|
||||
* @param jdbcConnection A JDBC {@link java.sql.Connection} which can be used to gauge the drivers level of support,
|
||||
* specifically for creating LOB references.
|
||||
* @return An appropriate {@link JdbcSupport} instance.
|
||||
*/
|
||||
public static JdbcSupport loadJdbcSupport(Connection jdbcConnection) {
|
||||
return new JdbcSupportImpl( useContextualLobCreation( jdbcConnection ) );
|
||||
}
|
||||
|
||||
private static final Class[] NO_ARG_SIG = new Class[0];
|
||||
private static final Object[] NO_ARGS = new Object[0];
|
||||
|
||||
/**
|
||||
* Basically here we are simply checking whether we can call the {@link Connection} methods for
|
||||
* LOB creation added in JDBC 4. We not only check whether the {@link Connection} declares these methods,
|
||||
* but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply
|
||||
* throwing an exception).
|
||||
*
|
||||
* @param jdbcConnection The connection whcih can be used in level-of-support testing.
|
||||
* @return True if the connection can be used to create LOBs; false otherwise.
|
||||
*/
|
||||
private static boolean useContextualLobCreation(Connection jdbcConnection) {
|
||||
if ( jdbcConnection == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Class connectionClass = Connection.class;
|
||||
Method createClobMethod = connectionClass.getMethod( "createClob", NO_ARG_SIG );
|
||||
if ( createClobMethod.getDeclaringClass().equals( Connection.class ) ) {
|
||||
// If we get here we are running in a jdk 1.6 (jdbc 4) environment...
|
||||
// Further check to make sure the driver actually implements the LOB creation methods. We
|
||||
// check against createClob() as indicative of all; should we check against all 3 explicitly?
|
||||
try {
|
||||
Object clob = createClobMethod.invoke( jdbcConnection, NO_ARGS );
|
||||
try {
|
||||
Method freeMethod = clob.getClass().getMethod( "free", NO_ARG_SIG );
|
||||
freeMethod.invoke( clob, NO_ARGS );
|
||||
}
|
||||
catch ( Throwable ignore ) {
|
||||
log.trace( "Unable to free CLOB created to test createClob() implementation : " + ignore );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
log.info( "createClob() method threw error : " + t );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( NoSuchMethodException ignore ) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -22,18 +22,18 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.lob;
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* Exposes a <tt>Reader</tt> as an <tt>InputStream</tt>
|
||||
* Exposes a {@link Reader} as an {@link InputStream}.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class ReaderInputStream extends InputStream {
|
||||
|
||||
private Reader reader;
|
||||
|
||||
public ReaderInputStream(Reader reader) {
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -77,6 +77,7 @@ import org.hibernate.engine.QueryParameters;
|
|||
import org.hibernate.engine.StatefulPersistenceContext;
|
||||
import org.hibernate.engine.Status;
|
||||
import org.hibernate.engine.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.query.FilterQueryPlan;
|
||||
import org.hibernate.engine.query.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.NativeSQLQueryPlan;
|
||||
|
@ -140,7 +141,7 @@ import org.hibernate.util.StringHelper;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public final class SessionImpl extends AbstractSessionImpl
|
||||
implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
|
||||
implements EventSource, org.hibernate.classic.Session, JDBCContext.Context, LobCreationContext {
|
||||
|
||||
// todo : need to find a clean way to handle the "event source" role
|
||||
// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
|
||||
|
@ -2001,6 +2002,23 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
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 );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,7 +20,6 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.loader;
|
||||
|
||||
|
@ -63,6 +62,7 @@ import org.hibernate.engine.SessionImplementor;
|
|||
import org.hibernate.engine.SubselectFetch;
|
||||
import org.hibernate.engine.TwoPhaseLoad;
|
||||
import org.hibernate.engine.TypedValue;
|
||||
import org.hibernate.engine.jdbc.ColumnNameCache;
|
||||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.event.PostLoadEvent;
|
||||
import org.hibernate.event.PreLoadEvent;
|
||||
|
@ -70,8 +70,6 @@ import org.hibernate.exception.JDBCExceptionHelper;
|
|||
import org.hibernate.hql.HolderInstantiator;
|
||||
import org.hibernate.impl.FetchingScrollableResultsImpl;
|
||||
import org.hibernate.impl.ScrollableResultsImpl;
|
||||
import org.hibernate.jdbc.ColumnNameCache;
|
||||
import org.hibernate.jdbc.ResultSetWrapper;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Loadable;
|
||||
|
@ -1839,7 +1837,9 @@ public abstract class Loader {
|
|||
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);
|
||||
|
|
|
@ -1,136 +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.lob;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.Blob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* A dummy implementation of <tt>java.sql.Blob</tt> that
|
||||
* may be used to insert new data into a BLOB.
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class BlobImpl implements Blob {
|
||||
|
||||
private InputStream stream;
|
||||
private int length;
|
||||
private boolean needsReset = false;
|
||||
|
||||
public BlobImpl(byte[] bytes) {
|
||||
this.stream = new ByteArrayInputStream(bytes);
|
||||
this.length = bytes.length;
|
||||
}
|
||||
|
||||
public BlobImpl(InputStream stream, int length) {
|
||||
this.stream = stream;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#length()
|
||||
*/
|
||||
public long length() throws SQLException {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#truncate(long)
|
||||
*/
|
||||
public void truncate(long pos) throws SQLException {
|
||||
excep();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#getBytes(long, int)
|
||||
*/
|
||||
public byte[] getBytes(long pos, int len) throws SQLException {
|
||||
excep(); return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#setBytes(long, byte[])
|
||||
*/
|
||||
public int setBytes(long pos, byte[] bytes) throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#setBytes(long, byte[], int, int)
|
||||
*/
|
||||
public int setBytes(long pos, byte[] bytes, int i, int j)
|
||||
throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#position(byte[], long)
|
||||
*/
|
||||
public long position(byte[] bytes, long pos) throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#getBinaryStream()
|
||||
*/
|
||||
public InputStream getBinaryStream() throws SQLException {
|
||||
try {
|
||||
if (needsReset) stream.reset();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new SQLException("could not reset reader");
|
||||
}
|
||||
needsReset = true;
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#setBinaryStream(long)
|
||||
*/
|
||||
public OutputStream setBinaryStream(long pos) throws SQLException {
|
||||
excep(); return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Blob#position(Blob, long)
|
||||
*/
|
||||
public long position(Blob blob, long pos) throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
private static void excep() {
|
||||
throw new UnsupportedOperationException("Blob may not be manipulated from creating session");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,160 +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.lob;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.Writer;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* A dummy implementation of <tt>java.sql.Clob</tt> that
|
||||
* may be used to insert new data into a CLOB.
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class ClobImpl implements Clob {
|
||||
|
||||
private Reader reader;
|
||||
private int length;
|
||||
private boolean needsReset = false;
|
||||
|
||||
public ClobImpl(String string) {
|
||||
reader = new StringReader(string);
|
||||
length = string.length();
|
||||
}
|
||||
|
||||
public ClobImpl(Reader reader, int length) {
|
||||
this.reader = reader;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#length()
|
||||
*/
|
||||
public long length() throws SQLException {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#truncate(long)
|
||||
*/
|
||||
public void truncate(long pos) throws SQLException {
|
||||
excep();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#getAsciiStream()
|
||||
*/
|
||||
public InputStream getAsciiStream() throws SQLException {
|
||||
try {
|
||||
if (needsReset) reader.reset();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new SQLException("could not reset reader");
|
||||
}
|
||||
needsReset = true;
|
||||
return new ReaderInputStream(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#setAsciiStream(long)
|
||||
*/
|
||||
public OutputStream setAsciiStream(long pos) throws SQLException {
|
||||
excep(); return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#getCharacterStream()
|
||||
*/
|
||||
public Reader getCharacterStream() throws SQLException {
|
||||
try {
|
||||
if (needsReset) reader.reset();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new SQLException("could not reset reader");
|
||||
}
|
||||
needsReset = true;
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#setCharacterStream(long)
|
||||
*/
|
||||
public Writer setCharacterStream(long pos) throws SQLException {
|
||||
excep(); return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#getSubString(long, int)
|
||||
*/
|
||||
public String getSubString(long pos, int len) throws SQLException {
|
||||
excep(); return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#setString(long, String)
|
||||
*/
|
||||
public int setString(long pos, String string) throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#setString(long, String, int, int)
|
||||
*/
|
||||
public int setString(long pos, String string, int i, int j)
|
||||
throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#position(String, long)
|
||||
*/
|
||||
public long position(String string, long pos) throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.sql.Clob#position(Clob, long)
|
||||
*/
|
||||
public long position(Clob colb, long pos) throws SQLException {
|
||||
excep(); return 0;
|
||||
}
|
||||
|
||||
|
||||
private static void excep() {
|
||||
throw new UnsupportedOperationException("Blob may not be manipulated from creating session");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,89 +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.lob;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.sql.Blob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class SerializableBlob implements Serializable, Blob {
|
||||
|
||||
private transient final Blob blob;
|
||||
|
||||
public SerializableBlob(Blob blob) {
|
||||
this.blob = blob;
|
||||
}
|
||||
|
||||
public Blob getWrappedBlob() {
|
||||
if ( blob==null ) {
|
||||
throw new IllegalStateException("Blobs may not be accessed after serialization");
|
||||
}
|
||||
else {
|
||||
return blob;
|
||||
}
|
||||
}
|
||||
|
||||
public long length() throws SQLException {
|
||||
return getWrappedBlob().length();
|
||||
}
|
||||
|
||||
public byte[] getBytes(long pos, int length) throws SQLException {
|
||||
return getWrappedBlob().getBytes(pos, length);
|
||||
}
|
||||
|
||||
public InputStream getBinaryStream() throws SQLException {
|
||||
return getWrappedBlob().getBinaryStream();
|
||||
}
|
||||
|
||||
public long position(byte[] pattern, long start) throws SQLException {
|
||||
return getWrappedBlob().position(pattern, start);
|
||||
}
|
||||
|
||||
public long position(Blob pattern, long start) throws SQLException {
|
||||
return getWrappedBlob().position(pattern, start);
|
||||
}
|
||||
|
||||
public int setBytes(long pos, byte[] bytes) throws SQLException {
|
||||
return getWrappedBlob().setBytes(pos, bytes);
|
||||
}
|
||||
|
||||
public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
|
||||
return getWrappedBlob().setBytes(pos, bytes, offset, len);
|
||||
}
|
||||
|
||||
public OutputStream setBinaryStream(long pos) throws SQLException {
|
||||
return getWrappedBlob().setBinaryStream(pos);
|
||||
}
|
||||
|
||||
public void truncate(long len) throws SQLException {
|
||||
getWrappedBlob().truncate(len);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,99 +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.lob;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class SerializableClob implements Serializable, Clob {
|
||||
|
||||
private transient final Clob clob;
|
||||
|
||||
public SerializableClob(Clob blob) {
|
||||
this.clob = blob;
|
||||
}
|
||||
|
||||
public Clob getWrappedClob() {
|
||||
if ( clob==null ) {
|
||||
throw new IllegalStateException("Clobs may not be accessed after serialization");
|
||||
}
|
||||
else {
|
||||
return clob;
|
||||
}
|
||||
}
|
||||
|
||||
public long length() throws SQLException {
|
||||
return getWrappedClob().length();
|
||||
}
|
||||
|
||||
public String getSubString(long pos, int length) throws SQLException {
|
||||
return getWrappedClob().getSubString(pos, length);
|
||||
}
|
||||
|
||||
public Reader getCharacterStream() throws SQLException {
|
||||
return getWrappedClob().getCharacterStream();
|
||||
}
|
||||
|
||||
public InputStream getAsciiStream() throws SQLException {
|
||||
return getWrappedClob().getAsciiStream();
|
||||
}
|
||||
|
||||
public long position(String searchstr, long start) throws SQLException {
|
||||
return getWrappedClob().position(searchstr, start);
|
||||
}
|
||||
|
||||
public long position(Clob searchstr, long start) throws SQLException {
|
||||
return getWrappedClob().position(searchstr, start);
|
||||
}
|
||||
|
||||
public int setString(long pos, String str) throws SQLException {
|
||||
return getWrappedClob().setString(pos, str);
|
||||
}
|
||||
|
||||
public int setString(long pos, String str, int offset, int len) throws SQLException {
|
||||
return getWrappedClob().setString(pos, str, offset, len);
|
||||
}
|
||||
|
||||
public OutputStream setAsciiStream(long pos) throws SQLException {
|
||||
return getWrappedClob().setAsciiStream(pos);
|
||||
}
|
||||
|
||||
public Writer setCharacterStream(long pos) throws SQLException {
|
||||
return getWrappedClob().setCharacterStream(pos);
|
||||
}
|
||||
|
||||
public void truncate(long len) throws SQLException {
|
||||
getWrappedClob().truncate(len);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +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
|
||||
~
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<p>
|
||||
This package defines dummy and wrapper implementations
|
||||
of <tt>java.sql.Clob</tt> and <tt>java.sql.Blob</tt>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -36,11 +36,14 @@ import org.dom4j.Node;
|
|||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.engine.Mapping;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.lob.BlobImpl;
|
||||
import org.hibernate.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 @@ import org.hibernate.util.ArrayHelper;
|
|||
* @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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -40,8 +40,10 @@ import org.hibernate.MappingException;
|
|||
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,36 +52,87 @@ import org.hibernate.util.ArrayHelper;
|
|||
*/
|
||||
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 );
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
|
||||
Clob value = rs.getClob(name);
|
||||
return rs.wasNull() ? null : new SerializableClob(value);
|
||||
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 {
|
||||
st.setClob( index, clob );
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -123,29 +176,6 @@ public class ClobType extends AbstractType {
|
|||
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 {
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
~ third-party contributors as indicated by either @author tags or express
|
||||
~ copyright attribution statements applied by the authors. All
|
||||
~ third-party contributions are distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-parent</artifactId>
|
||||
<version>3.5.0-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hibernate-jdbc3-testing</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>JDBC3-JdbcSupport Testing</name>
|
||||
<description>Test support of JDBC3 through JdbcSupport</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>8.4-701.jdbc4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -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 );
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,94 @@
|
|||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
~ third-party contributors as indicated by either @author tags or express
|
||||
~ copyright attribution statements applied by the authors. All
|
||||
~ third-party contributions are distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-parent</artifactId>
|
||||
<version>3.5.0-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- TODO : move this to local settings.xml -->
|
||||
<jdbc4_jdk>/opt/java/jdk-1.6</jdbc4_jdk>
|
||||
</properties>
|
||||
|
||||
<artifactId>hibernate-jdbc4-testing</artifactId>
|
||||
<name>JDBC4-JdbcSupport Testing</name>
|
||||
<description>Test support of JDBC4 through JdbcSupport</description>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<verbose>true</verbose>
|
||||
<fork>true</fork>
|
||||
<executable>${jdbc4_jdk}/bin/javac</executable>
|
||||
<compilerVersion>1.6</compilerVersion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<jvm>${jdbc4_jdk}/bin/java</jvm>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>8.4-701.jdbc4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>11.1.0.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.engine.jdbc.jdbc4;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.NClob;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.JdbcSupportLoader;
|
||||
import org.hibernate.engine.jdbc.ContextualLobCreator;
|
||||
import org.hibernate.engine.jdbc.BlobImplementer;
|
||||
import org.hibernate.engine.jdbc.ClobImplementer;
|
||||
import org.hibernate.engine.jdbc.NClobImplementer;
|
||||
import org.hibernate.engine.jdbc.NonContextualLobCreator;
|
||||
import org.hibernate.engine.jdbc.WrappedBlob;
|
||||
import org.hibernate.engine.jdbc.WrappedClob;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcSupportTest extends TestCase {
|
||||
private interface Envionment {
|
||||
public String getDriver();
|
||||
public String getUrl();
|
||||
public String getUser();
|
||||
public String getPass();
|
||||
|
||||
public void verifyCreator(LobCreator lobCreator);
|
||||
public void verifyBlob(Blob blob);
|
||||
public void verifyClob(Clob clob);
|
||||
public void verifyNClob(Clob nclob);
|
||||
}
|
||||
|
||||
private abstract class ContextualEnvironment implements Envionment {
|
||||
public void verifyCreator(LobCreator lobCreator) {
|
||||
assertTrue( lobCreator instanceof ContextualLobCreator );
|
||||
}
|
||||
|
||||
public void verifyBlob(Blob blob) {
|
||||
assertFalse( blob instanceof BlobImplementer );
|
||||
}
|
||||
|
||||
public void verifyClob(Clob clob) {
|
||||
assertFalse( clob instanceof ClobImplementer );
|
||||
}
|
||||
|
||||
public void verifyNClob(Clob nclob) {
|
||||
assertFalse( nclob instanceof NClobImplementer );
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class NonContextualEnvironment implements Envionment {
|
||||
public void verifyCreator(LobCreator lobCreator) {
|
||||
assertTrue( lobCreator instanceof NonContextualLobCreator );
|
||||
}
|
||||
|
||||
public void verifyBlob(Blob blob) {
|
||||
assertTrue( blob instanceof BlobImplementer );
|
||||
}
|
||||
|
||||
public void verifyClob(Clob clob) {
|
||||
assertTrue( clob instanceof ClobImplementer );
|
||||
}
|
||||
|
||||
public void verifyNClob(Clob nclob) {
|
||||
assertTrue( nclob instanceof NClobImplementer );
|
||||
}
|
||||
}
|
||||
|
||||
private Envionment POSTGRESQL = new NonContextualEnvironment() {
|
||||
public String getDriver() {
|
||||
return "org.postgresql.Driver";
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return "jdbc:postgresql://vmg03.mw.lab.eng.bos.redhat.com:5432:platformae";
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return "sebersole";
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return "sebersole";
|
||||
}
|
||||
};
|
||||
|
||||
private Envionment MYSQL = new ContextualEnvironment() {
|
||||
public String getDriver() {
|
||||
return "com.mysql.jdbc.Driver";
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return "jdbc:mysql://vmg02.mw.lab.eng.bos.redhat.com/sebersole";
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return "sebersole";
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return "sebersole";
|
||||
}
|
||||
};
|
||||
|
||||
private Envionment ORACLE9i = new ContextualEnvironment() {
|
||||
public String getDriver() {
|
||||
return "oracle.jdbc.driver.OracleDriver";
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return "jdbc:oracle:thin:@dev20.qa.atl.jboss.com:1521:qa";
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return "sebersole";
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return "sebersole";
|
||||
}
|
||||
};
|
||||
|
||||
private Envionment ORACLE10g = new ContextualEnvironment() {
|
||||
public String getDriver() {
|
||||
return "oracle.jdbc.driver.OracleDriver";
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return "jdbc:oracle:thin:@vmg05.mw.lab.eng.bos.redhat.com:1521:qaora10";
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return "sebersole";
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return "sebersole";
|
||||
}
|
||||
};
|
||||
|
||||
private Envionment ORACLE11g = new ContextualEnvironment() {
|
||||
public String getDriver() {
|
||||
return "oracle.jdbc.driver.OracleDriver";
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return "jdbc:oracle:thin:@dev04.qa.atl2.redhat.com:1521:qaora11";
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return "sebersole";
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return "sebersole";
|
||||
}
|
||||
};
|
||||
|
||||
private Envionment ORACLE_RAC = new ContextualEnvironment() {
|
||||
public String getDriver() {
|
||||
return "oracle.jdbc.driver.OracleDriver";
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=vmg24-vip.mw.lab.eng.bos.redhat.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=vmg25-vip.mw.lab.eng.bos.redhat.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=qarac.jboss))";
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return "sebersole";
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return "sebersole";
|
||||
}
|
||||
};
|
||||
|
||||
private Envionment envionment = ORACLE11g;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
Class.forName( envionment.getDriver() );
|
||||
}
|
||||
|
||||
public void testConnectedLobCreator() throws SQLException {
|
||||
final Connection connection = DriverManager.getConnection( envionment.getUrl(), envionment.getUser(), envionment.getPass() );
|
||||
final LobCreationContext lobCreationContext = new LobCreationContext() {
|
||||
public Object execute(Callback callback) {
|
||||
try {
|
||||
return callback.executeOnConnection( connection );
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new RuntimeException( "Unexpected sql exception", e );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( connection ).getLobCreator( lobCreationContext );
|
||||
envionment.verifyCreator( lobCreator );
|
||||
|
||||
Blob blob = lobCreator.createBlob( new byte[] {} );
|
||||
envionment.verifyBlob( blob );
|
||||
blob = lobCreator.wrap( blob );
|
||||
assertTrue( blob instanceof WrappedBlob );
|
||||
|
||||
Clob clob = lobCreator.createClob( "Hi" );
|
||||
envionment.verifyClob( clob );
|
||||
clob = lobCreator.wrap( clob );
|
||||
assertTrue( clob instanceof WrappedClob );
|
||||
|
||||
Clob nclob = lobCreator.createNClob( "Hi" );
|
||||
envionment.verifyNClob( nclob );
|
||||
assertTrue( NClob.class.isInstance( nclob ) );
|
||||
nclob = lobCreator.wrap( nclob );
|
||||
assertTrue( nclob instanceof WrappedClob );
|
||||
|
||||
blob.free();
|
||||
clob.free();
|
||||
nclob.free();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
public void testLegacyLobCreator() throws SQLException {
|
||||
LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( null ).getLobCreator();
|
||||
|
||||
Blob blob = lobCreator.createBlob( new byte[] {} );
|
||||
assertTrue( blob instanceof BlobImplementer );
|
||||
blob = lobCreator.wrap( blob );
|
||||
assertTrue( blob instanceof WrappedBlob );
|
||||
|
||||
Clob clob = lobCreator.createClob( "Hi" );
|
||||
assertTrue( clob instanceof ClobImplementer );
|
||||
clob = lobCreator.wrap( clob );
|
||||
assertTrue( clob instanceof WrappedClob );
|
||||
|
||||
Clob nclob = lobCreator.createNClob( "Hi" );
|
||||
assertTrue( nclob instanceof NClobImplementer );
|
||||
assertTrue( NClob.class.isInstance( nclob ) );
|
||||
nclob = lobCreator.wrap( nclob );
|
||||
assertTrue( nclob instanceof WrappedClob );
|
||||
|
||||
blob.free();
|
||||
clob.free();
|
||||
nclob.free();
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -118,10 +118,6 @@
|
|||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- require at least JDK 1.5 to run the build -->
|
||||
<!-- ... -->
|
||||
<!-- we need at least Maven 2.0.8 because of a bug fix affecting our antlr usage -->
|
||||
<!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
|
@ -135,9 +131,12 @@
|
|||
<configuration>
|
||||
<rules>
|
||||
<requireJavaVersion>
|
||||
<version>[1.5,)</version>
|
||||
<!-- require JDK 1.5 to run the build -->
|
||||
<version>[1.5,1.6)</version>
|
||||
</requireJavaVersion>
|
||||
<requireMavenVersion>
|
||||
<!-- we need at least Maven 2.0.8 because of a bug fix affecting our antlr usage -->
|
||||
<!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
|
||||
<version>(2.0.7,)</version>
|
||||
</requireMavenVersion>
|
||||
</rules>
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -32,9 +32,10 @@
|
|||
<module>jmx</module>
|
||||
<module>testing</module>
|
||||
<module>testsuite</module>
|
||||
<module>jdbc3-testing</module>
|
||||
<module>jdbc4-testing</module>
|
||||
<module>tutorials</module>
|
||||
<module>hibernate-maven-plugin</module>
|
||||
<!--
|
||||
<!--
|
||||
Need to scope bytecode providers first...
|
||||
<module>bytecode-cglib</module>
|
||||
<module>bytecode-javassist</module>
|
||||
|
|
Loading…
Reference in New Issue