Hibernate SVN: r19302 - core/branches/Branch_3_3_2_GA_CP/jdbc4-testing.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-27 03:41:28 -0400 (Tue, 27 Apr 2010)
New Revision: 19302
Modified:
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/
Log:
ignore eclipse metadata files
Property changes on: core/branches/Branch_3_3_2_GA_CP/jdbc4-testing
___________________________________________________________________
Name: svn:ignore
+ .settings
target
.classpath
.project
14 years, 7 months
Hibernate SVN: r19301 - core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/util.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-27 03:37:53 -0400 (Tue, 27 Apr 2010)
New Revision: 19301
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/util/SerializationHelper.java
Log:
JBPAPP-4180 HHH-2412 Support for JDBC4
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/util/SerializationHelper.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/util/SerializationHelper.java 2010-04-27 07:17:09 UTC (rev 19300)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/util/SerializationHelper.java 2010-04-27 07:37:53 UTC (rev 19301)
@@ -223,8 +223,10 @@
}
}
- /**
- * Deserializes an Object from an array of bytes.
+ /**
+ * Deserializes an object from an array of bytes using the Thread Context
+ * ClassLoader (TCCL). If there is no TCCL set, the classloader of the calling
+ * class is used.
* <p/>
* Delegates to {@link #deserialize(byte[], ClassLoader)}
*
@@ -261,9 +263,12 @@
/**
- * Custom ObjectInputStream implementation to more appropriately handle classloading
- * within app servers (mainly jboss - hence this class inspired by jboss's class of
- * the same purpose).
+ * By default, to resolve the classes being deserialized JDK serialization uses the
+ * classes loader which loaded the class which initiated the deserialization call. Here
+ * that would be hibernate classes. However, there are cases where that is not the correct
+ * class loader to use; mainly here we are worried about deserializing user classes in
+ * environments (app servers, etc) where Hibernate is on a parent classes loader. To
+ * facilitate for that we allow passing in the class loader we should use.
*/
private static final class CustomObjectInputStream extends ObjectInputStream {
private final ClassLoader loader;
@@ -285,7 +290,8 @@
log.trace( "Unable to locate class using given classloader" );
}
}
-
+ // By default delegate to normal JDK deserialization which will use the class loader
+ // of the class which is calling this deserialization.
return super.resolveClass( v );
}
}
14 years, 7 months
Hibernate SVN: r19300 - in core/branches/Branch_3_3_2_GA_CP: core/src/main/java/org/hibernate and 27 other directories.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-27 03:17:09 -0400 (Tue, 27 Apr 2010)
New Revision: 19300
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/
core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/
core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties
Removed:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/lob/
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java
Log:
JBPAPP-4180 HHH-2412 Support for JDBC4
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -28,6 +28,7 @@
import java.io.InputStream;
import java.io.Reader;
import java.io.Serializable;
+import java.io.ByteArrayOutputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.util.Iterator;
@@ -35,12 +36,13 @@
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.HibernateIterator;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.StreamUtils;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.lob.BlobImpl;
-import org.hibernate.lob.ClobImpl;
-import org.hibernate.lob.SerializableBlob;
-import org.hibernate.lob.SerializableClob;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.type.AnyType;
@@ -387,57 +389,166 @@
}
/**
- * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+ * Create a new {@link Blob}. The returned object will be initially immutable.
*
* @param bytes a byte array
* @return the Blob
+ * @deprecated Use {@link #createBlob(byte[], Session)} instead
*/
public static Blob createBlob(byte[] bytes) {
- return new SerializableBlob( new BlobImpl( bytes ) );
+ return NonContextualLobCreator.INSTANCE.wrap(
+ NonContextualLobCreator.INSTANCE.createBlob( bytes )
+ );
}
/**
- * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+ * Create a new {@link Blob}.
*
+ * @param bytes a byte array
+ * @param session The session in which the {@link Blob} will be used.
+ * @return the Blob
+ */
+ public static Blob createBlob(byte[] bytes, Session session) {
+ // todo : wrap?
+ return getLobCreator( session ).createBlob( bytes );
+ }
+
+ public static LobCreator getLobCreator(Session session) {
+ return getLobCreator( ( SessionImplementor ) session );
+ }
+
+ public static LobCreator getLobCreator(SessionImplementor session) {
+ return session.getFactory()
+ .getSettings()
+ .getJdbcSupport()
+ .getLobCreator( ( LobCreationContext ) session );
+ }
+
+ /**
+ * Create a new {@link Blob}. The returned object will be initially immutable.
+ *
* @param stream a binary stream
* @param length the number of bytes in the stream
* @return the Blob
+ * @deprecated Use {@link #createBlob(InputStream, long, Session)} instead
*/
public static Blob createBlob(InputStream stream, int length) {
- return new SerializableBlob( new BlobImpl( stream, length ) );
+ return NonContextualLobCreator.INSTANCE.wrap(
+ NonContextualLobCreator.INSTANCE.createBlob( stream, length )
+ );
}
/**
- * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+ * Create a new {@link Blob}. The returned object will be initially immutable.
*
* @param stream a binary stream
+ * @param length the number of bytes in the stream
* @return the Blob
- * @throws IOException
+ * @deprecated Use {@link #createBlob(InputStream, long, Session)} instead
*/
+ public static Blob createBlob(InputStream stream, long length) {
+ return NonContextualLobCreator.INSTANCE.wrap(
+ NonContextualLobCreator.INSTANCE.createBlob( stream, length )
+ );
+ }
+
+ /**
+ * Create a new {@link Blob}.
+ *
+ * @param stream a binary stream
+ * @param length the number of bytes in the stream
+ * @param session The session in which the {@link Blob} will be used.
+ * @return the Blob
+ */
+ public static Blob createBlob(InputStream stream, long length, Session session) {
+ // todo : wrap?
+ return getLobCreator( session ).createBlob( stream, length );
+ }
+
+ /**
+ * Create a new {@link Blob}. The returned object will be initially immutable.
+ * <p/>
+ * NOTE: this method will read the entire contents of the incoming stream in order to properly
+ * handle the {@link Blob#length()} method. If you do not want the stream read, use the
+ * {@link #createBlob(InputStream,long)} version instead.
+ *
+ * @param stream a binary stream
+ * @return the Blob
+ * @throws IOException Indicates an I/O problem accessing the stream
+ * @deprecated Use {@link #createBlob(InputStream, long, Session)} instead
+ */
public static Blob createBlob(InputStream stream) throws IOException {
- return new SerializableBlob( new BlobImpl( stream, stream.available() ) );
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream( stream.available() );
+ StreamUtils.copy( stream, buffer );
+ return createBlob( buffer.toByteArray() );
}
/**
- * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
+ * Create a new {@link Clob}. The returned object will be initially immutable.
*
- * @param string a <tt>String</tt>
+ * @param string The string data
+ * @return The created {@link Clob}
+ * @deprecated Use {@link #createClob(String, Session)} instead
*/
public static Clob createClob(String string) {
- return new SerializableClob( new ClobImpl( string ) );
+ return NonContextualLobCreator.INSTANCE.wrap(
+ NonContextualLobCreator.INSTANCE.createClob( string )
+ );
}
/**
- * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
+ * Create a new {@link Clob}.
*
+ * @param string The string data
+ * @param session The session in which the {@link Clob} will be used.
+ * @return The created {@link Clob}
+ */
+ public static Clob createClob(String string, Session session) {
+ // todo : wrap?
+ return getLobCreator( session ).createClob( string );
+ }
+
+ /**
+ * Create a new {@link Clob}. The returned object will be initially immutable.
+ *
* @param reader a character stream
* @param length the number of characters in the stream
+ * @return The created {@link Clob}
+ * @deprecated Use {@link #createClob(Reader,long,Session)} instead
*/
public static Clob createClob(Reader reader, int length) {
- return new SerializableClob( new ClobImpl( reader, length ) );
+ return NonContextualLobCreator.INSTANCE.wrap(
+ NonContextualLobCreator.INSTANCE.createClob( reader, length )
+ );
}
/**
+ * Create a new {@link Clob}. The returned object will be initially immutable.
+ *
+ * @param reader a character stream
+ * @param length the number of characters in the stream
+ * @return The created {@link Clob}
+ * @deprecated Use {@link #createClob(Reader,long,Session)} instead
+ */
+ public static Clob createClob(Reader reader, long length) {
+ return NonContextualLobCreator.INSTANCE.wrap(
+ NonContextualLobCreator.INSTANCE.createClob( reader, length )
+ );
+ }
+
+ /**
+ * Create a new {@link Clob}.
+ *
+ * @param reader a character stream
+ * @param length the number of characters in the stream
+ * @param session The session in which the {@link Clob} will be used.
+ * @return The created {@link Clob}
+ */
+ public static Clob createClob(Reader reader, long length, Session session) {
+ return getLobCreator( session ).createClob( reader, length );
+ }
+
+ /**
* Close an <tt>Iterator</tt> created by <tt>iterate()</tt> immediately,
* instead of waiting until the session is closed or disconnected.
*
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/Settings.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -33,6 +33,7 @@
import org.hibernate.cache.RegionFactory;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.jdbc.JdbcSupport;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.hql.QueryTranslatorFactory;
import org.hibernate.jdbc.BatcherFactory;
@@ -96,7 +97,7 @@
private EntityTuplizerFactory entityTuplizerFactory;
// private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907
// private BytecodeProvider bytecodeProvider;
-
+ private JdbcSupport jdbcSupport;
/**
* Package protected constructor
*/
@@ -297,7 +298,9 @@
// return componentTuplizerFactory;
// }
-
+ public JdbcSupport getJdbcSupport(){
+ return jdbcSupport;
+ }
// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// void setShowSqlEnabled(boolean b) {
@@ -492,7 +495,9 @@
// this.componentTuplizerFactory = componentTuplizerFactory;
// }
-
+ void setJdbcSupport(JdbcSupport jdbcSupport){
+ this.jdbcSupport = jdbcSupport;
+ }
// public BytecodeProvider getBytecodeProvider() {
// return bytecodeProvider;
// }
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -47,6 +47,8 @@
import org.hibernate.connection.ConnectionProviderFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.resolver.DialectFactory;
+import org.hibernate.engine.jdbc.JdbcSupport;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.exception.SQLExceptionConverterFactory;
import org.hibernate.hql.QueryTranslatorFactory;
@@ -97,7 +99,7 @@
boolean metaReportsDDLCausesTxnCommit = false;
boolean metaReportsDDLInTxnSupported = true;
Dialect dialect = null;
-
+ JdbcSupport jdbcSupport = null;
// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
// The need for it is intended to be alleviated with future developement, thus it is
// not defined as an Environment constant...
@@ -115,7 +117,7 @@
log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
dialect = DialectFactory.buildDialect( props, conn );
-
+ jdbcSupport = JdbcSupportLoader.loadJdbcSupport( conn );
metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
metaSupportsBatchUpdates = meta.supportsBatchUpdates();
metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
@@ -145,7 +147,10 @@
settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
settings.setDialect( dialect );
-
+ if ( jdbcSupport == null ){
+ jdbcSupport = JdbcSupportLoader.loadJdbcSupport( null );
+ }
+ settings.setJdbcSupport( jdbcSupport );
//use dialect default properties
final Properties properties = new Properties();
properties.putAll( dialect.getDefaultProperties() );
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/AbstractLobCreator.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Blob;
+import java.sql.Clob;
+
+/**
+ * Convenient base class for proxy-based LobCreator for handling wrapping.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractLobCreator implements LobCreator {
+ /**
+ * {@inheritDoc}
+ */
+ public Blob wrap(Blob blob) {
+ return SerializableBlobProxy.generateProxy( blob );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob wrap(Clob clob) {
+ if ( SerializableNClobProxy.isNClob( clob ) ) {
+ return SerializableNClobProxy.generateProxy( clob );
+ }
+ else {
+ return SerializableClobProxy.generateProxy( clob );
+ }
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobImplementer.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,32 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+/**
+ * Marker interface for non-contextually created {@link java.sql.Blob} instances..
+ *
+ * @author Steve Ebersole
+ */
+public interface BlobImplementer {
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/BlobProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,163 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * Manages aspects of proxying {@link Blob Blobs} for non-contextual creation, including proxy creation and
+ * handling proxy invocations.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class BlobProxy implements InvocationHandler {
+ private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, BlobImplementer.class };
+
+ private InputStream stream;
+ private long length;
+ private boolean needsReset = false;
+
+ /**
+ * Ctor used to build {@link Blob} from byte array.
+ *
+ * @param bytes The byte array
+ * @see #generateProxy(byte[])
+ */
+ private BlobProxy(byte[] bytes) {
+ this.stream = new ByteArrayInputStream( bytes );
+ this.length = bytes.length;
+ }
+
+ /**
+ * Ctor used to build {@link Blob} from a stream.
+ *
+ * @param stream The binary stream
+ * @param length The length of the stream
+ * @see #generateProxy(java.io.InputStream, long)
+ */
+ private BlobProxy(InputStream stream, long length) {
+ this.stream = stream;
+ this.length = length;
+ }
+
+ private long getLength() {
+ return length;
+ }
+
+ private InputStream getStream() throws SQLException {
+ try {
+ if (needsReset) {
+ stream.reset();
+ }
+ }
+ catch ( IOException ioe) {
+ throw new SQLException("could not reset reader");
+ }
+ needsReset = true;
+ return stream;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws UnsupportedOperationException if any methods other than {@link Blob#length()}
+ * or {@link Blob#getBinaryStream} are invoked.
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if ( "length".equals( method.getName() ) ) {
+ return new Long( getLength() );
+ }
+ if ( "getBinaryStream".equals( method.getName() ) && method.getParameterTypes().length == 0 ) {
+ return getStream();
+ }
+ if ( "free".equals( method.getName() ) ) {
+ stream.close();
+ return null;
+ }
+ if ( "toString".equals( method.getName() ) ) {
+ return this.toString();
+ }
+ if ( "equals".equals( method.getName() ) ) {
+ return Boolean.valueOf( proxy == args[0] );
+ }
+ if ( "hashCode".equals( method.getName() ) ) {
+ return new Integer( this.hashCode() );
+ }
+ throw new UnsupportedOperationException( "Blob may not be manipulated from creating session" );
+ }
+
+ /**
+ * Generates a BlobImpl proxy using byte data.
+ *
+ * @param bytes The data to be created as a Blob.
+ *
+ * @return The generated proxy.
+ */
+ public static Blob generateProxy(byte[] bytes) {
+ return ( Blob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new BlobProxy( bytes )
+ );
+ }
+
+ /**
+ * Generates a BlobImpl proxy using a given number of bytes from an InputStream.
+ *
+ * @param stream The input stream of bytes to be created as a Blob.
+ * @param length The number of bytes from stream to be written to the Blob.
+ *
+ * @return The generated proxy.
+ */
+ public static Blob generateProxy(InputStream stream, long length) {
+ return ( Blob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new BlobProxy( stream, length )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ private static ClassLoader getProxyClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if ( cl == null ) {
+ cl = BlobImplementer.class.getClassLoader();
+ }
+ return cl;
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobImplementer.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,32 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+/**
+ * Marker interface for non-contextually created {@link java.sql.Clob} instances..
+ *
+ * @author Steve Ebersole
+ */
+public interface ClobImplementer {
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ClobProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,177 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Manages aspects of proxying {@link Clob Clobs} for non-contextual creation, including proxy creation and
+ * handling proxy invocations.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class ClobProxy implements InvocationHandler {
+ private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, ClobImplementer.class };
+
+ private Reader reader;
+ private long length;
+ private boolean needsReset = false;
+
+
+ /**
+ * Ctor used to build {@link Clob} from string data.
+ *
+ * @param string The byte array
+ * @see #generateProxy(String)
+ */
+ protected ClobProxy(String string) {
+ reader = new StringReader(string);
+ length = string.length();
+ }
+
+ /**
+ * Ctor used to build {@link Clob} from a reader.
+ *
+ * @param reader The character reader.
+ * @param length The length of the reader stream.
+ * @see #generateProxy(java.io.Reader, long)
+ */
+ protected ClobProxy(Reader reader, long length) {
+ this.reader = reader;
+ this.length = length;
+ }
+
+ protected long getLength() {
+ return length;
+ }
+
+ protected InputStream getAsciiStream() throws SQLException {
+ resetIfNeeded();
+ return new ReaderInputStream( reader );
+ }
+
+ protected Reader getCharacterStream() throws SQLException {
+ resetIfNeeded();
+ return reader;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws UnsupportedOperationException if any methods other than {@link Clob#length()},
+ * {@link Clob#getAsciiStream()}, or {@link Clob#getCharacterStream()} are invoked.
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if ( "length".equals( method.getName() ) ) {
+ return new Long( getLength() );
+ }
+ if ( "getAsciiStream".equals( method.getName() ) ) {
+ return getAsciiStream();
+ }
+ if ( "getCharacterStream".equals( method.getName() ) ) {
+ return getCharacterStream();
+ }
+ if ( "free".equals( method.getName() ) ) {
+ reader.close();
+ return null;
+ }
+ if ( "toString".equals( method.getName() ) ) {
+ return this.toString();
+ }
+ if ( "equals".equals( method.getName() ) ) {
+ return Boolean.valueOf( proxy == args[0] );
+ }
+ if ( "hashCode".equals( method.getName() ) ) {
+ return new Integer( this.hashCode() );
+ }
+ throw new UnsupportedOperationException( "Clob may not be manipulated from creating session" );
+ }
+
+ protected void resetIfNeeded() throws SQLException {
+ try {
+ if ( needsReset ) {
+ reader.reset();
+ }
+ }
+ catch ( IOException ioe ) {
+ throw new SQLException( "could not reset reader" );
+ }
+ needsReset = true;
+ }
+
+ /**
+ * Generates a {@link Clob} proxy using the string data.
+ *
+ * @param string The data to be wrapped as a {@link Clob}.
+ *
+ * @return The generated proxy.
+ */
+ public static Clob generateProxy(String string) {
+ return ( Clob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new ClobProxy( string )
+ );
+ }
+
+ /**
+ * Generates a {@link Clob} proxy using a character reader of given length.
+ *
+ * @param reader The character reader
+ * @param length The length of the character reader
+ *
+ * @return The generated proxy.
+ */
+ public static Clob generateProxy(Reader reader, long length) {
+ return ( Clob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new ClobProxy( reader, length )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ protected static ClassLoader getProxyClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if ( cl == null ) {
+ cl = ClobImplementer.class.getClassLoader();
+ }
+ return cl;
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Cache of column-name -> column-index resolutions
+ *
+ * @author Steve Ebersole
+ */
+public class ColumnNameCache {
+ public static final float LOAD_FACTOR = .75f;
+
+ private final Map columnNameToIndexCache;
+
+ public ColumnNameCache(int columnCount) {
+ // should *not* need to grow beyond the size of the total number of columns in the rs
+ this.columnNameToIndexCache = new HashMap( columnCount + (int)( columnCount * LOAD_FACTOR ) + 1, LOAD_FACTOR );
+ }
+
+ public int getIndexForColumnName(String columnName, ResultSet rs) throws SQLException {
+ Integer cached = ( Integer ) columnNameToIndexCache.get( columnName );
+ if ( cached != null ) {
+ return cached.intValue();
+ }
+ else {
+ int index = rs.findColumn( columnName );
+ columnNameToIndexCache.put( columnName, new Integer(index) );
+ return index;
+ }
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ContextualLobCreator.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,238 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+
+/**
+ * {@link LobCreator} implementation using contextual creation against the JDBC {@link java.sql.Connection} class's LOB creation
+ * methods.
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class ContextualLobCreator extends AbstractLobCreator implements LobCreator {
+ private LobCreationContext lobCreationContext;
+
+ public ContextualLobCreator(LobCreationContext lobCreationContext) {
+ this.lobCreationContext = lobCreationContext;
+ }
+
+ /**
+ * Create the basic contextual BLOB reference.
+ *
+ * @return The created BLOB reference.
+ */
+ public Blob createBlob() {
+ return ( Blob ) lobCreationContext.execute( CREATE_BLOB_CALLBACK );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Blob createBlob(byte[] bytes) {
+ try {
+ Blob blob = createBlob();
+ blob.setBytes( 1, bytes );
+ return blob;
+ }
+ catch ( SQLException e ) {
+ throw new JDBCException( "Unable to set BLOB bytes after creation", e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Blob createBlob(InputStream inputStream, long length) {
+ try {
+ Blob blob = createBlob();
+ OutputStream byteStream = blob.setBinaryStream( 1 );
+ StreamUtils.copy( inputStream, byteStream );
+ byteStream.flush();
+ byteStream.close();
+ // todo : validate length written versus length given?
+ return blob;
+ }
+ catch ( SQLException e ) {
+ throw new JDBCException( "Unable to prepare BLOB binary stream for writing",e );
+ }
+ catch ( IOException e ) {
+ throw new HibernateException( "Unable to write stream contents to BLOB", e );
+ }
+ }
+
+ /**
+ * Create the basic contextual CLOB reference.
+ *
+ * @return The created CLOB reference.
+ */
+ public Clob createClob() {
+ return ( Clob ) lobCreationContext.execute( CREATE_CLOB_CALLBACK );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createClob(String string) {
+ try {
+ Clob clob = createClob();
+ clob.setString( 1, string );
+ return clob;
+ }
+ catch ( SQLException e ) {
+ throw new JDBCException( "Unable to set CLOB string after creation", e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createClob(Reader reader, long length) {
+ try {
+ Clob clob = createClob();
+ Writer writer = clob.setCharacterStream( 1 );
+ StreamUtils.copy( reader, writer );
+ writer.flush();
+ writer.close();
+ return clob;
+ }
+ catch ( SQLException e ) {
+ throw new JDBCException( "Unable to prepare CLOB stream for writing", e );
+ }
+ catch ( IOException e ) {
+ throw new HibernateException( "Unable to write CLOB stream content", e );
+ }
+ }
+
+ /**
+ * Create the basic contextual NCLOB reference.
+ *
+ * @return The created NCLOB reference.
+ */
+ public Clob createNClob() {
+ return ( Clob ) lobCreationContext.execute( CREATE_NCLOB_CALLBACK );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createNClob(String string) {
+ try {
+ Clob clob = createNClob();
+ clob.setString( 1, string );
+ return clob;
+ }
+ catch ( SQLException e ) {
+ throw new JDBCException( "Unable to set NCLOB string after creation", e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createNClob(Reader reader, long length) {
+ try {
+ Clob clob = createNClob();
+ Writer writer = clob.setCharacterStream( 1 );
+ StreamUtils.copy( reader, writer );
+ writer.flush();
+ writer.close();
+ return clob;
+ }
+ catch ( SQLException e ) {
+ throw new JDBCException( "Unable to prepare NCLOB stream for writing", e );
+ }
+ catch ( IOException e ) {
+ throw new HibernateException( "Unable to write NCLOB stream content", e );
+ }
+ }
+
+
+ private static final Class[] CREATION_METHOD_SIG = new Class[0];
+ private static final Object[] CREATION_METHOD_ARGS = new Object[0];
+
+ private static final LobCreationContext.Callback CREATE_BLOB_CALLBACK;
+ private static final LobCreationContext.Callback CREATE_CLOB_CALLBACK;
+ private static final LobCreationContext.Callback CREATE_NCLOB_CALLBACK;
+
+ static {
+ CREATE_BLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createBlob" ) );
+ CREATE_CLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createClob" ) );
+ CREATE_NCLOB_CALLBACK = new CallbackImpl( getConnectionlobCreationMethod( "createNClob" ) );
+ }
+
+ private static class CallbackImpl implements LobCreationContext.Callback {
+ private final Method creationMethod;
+
+ private CallbackImpl(Method creationMethod) {
+ this.creationMethod = creationMethod;
+ }
+
+ public Object executeOnConnection(Connection connection) throws SQLException {
+ try {
+ return creationMethod.invoke( connection, CREATION_METHOD_ARGS );
+ }
+ catch ( InvocationTargetException e ) {
+ if ( e.getTargetException() instanceof SQLException ) {
+ throw ( SQLException ) e.getTargetException();
+ }
+ else {
+ throw new HibernateException( "Exception invoking " + creationMethod.getName(), e.getTargetException() );
+ }
+ }
+ catch ( AbstractMethodError e ) {
+ // this again is a big big error...
+ throw new IllegalStateException( "Useable implementation of " + creationMethod.getName() + " not found." );
+ }
+ catch ( IllegalAccessException e ) {
+ // this again is a big big error...
+ throw new IllegalStateException( "Illegal access attempt on JDBC method " + creationMethod.getName() );
+ }
+ }
+ }
+
+ private static Method getConnectionlobCreationMethod(String methodName) {
+ try {
+ return Connection.class.getMethod( methodName, CREATION_METHOD_SIG );
+ }
+ catch ( NoSuchMethodException e ) {
+ // this is a big big error if we get here and these methods are not part of the Connection interface...
+ throw new IllegalStateException( "JDBC driver did not implement " + methodName);
+ }
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupport.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,65 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.ResultSet;
+
+/**
+ * Isolates Hibernate interactions with JDBC in terms of variations between JDBC 3 (JDK 1.4 and 1.5)
+ * and JDBC 4 (JDK 1.6).
+ *
+ * @author Steve Ebersole
+ */
+public interface JdbcSupport {
+ /**
+ * Creates an instance of a {@link LobCreator} that does not use the underlying JDBC {@link java.sql.Connection}
+ * to create LOBs.
+ * <p/>
+ * This method is here solely to support the older, now-deprecated method of creating LOBs via
+ * the various {@link org.hibernate.Hibernate#createBlob} and {@link org.hibernate.Hibernate#createClob} methods on
+ * {@link org.hibernate.Hibernate}.
+ *
+ * @return The LOB creator.
+ * @deprecated Use {@link #getLobCreator(LobCreationContext)} instead.
+ */
+ public LobCreator getLobCreator();
+
+ /**
+ * Create an instance of a {@link LobCreator} appropriate for the current envionment, mainly meant to account for
+ * variance between JDBC 4 (<= JDK 1.6) and JDBC3 (>= JDK 1.5).
+ *
+ * @param lobCreationContext The context in which the LOB is being created
+ * @return The LOB creator.
+ */
+ public LobCreator getLobCreator(LobCreationContext lobCreationContext);
+
+ /**
+ * Wrap the given {@link ResultSet} in one that caches the column-name -> column-index resolution.
+ *
+ * @param resultSet The {@link ResultSet} to wrap.
+ * @param columnNameCache The resolution cache.
+ * @return The wrapper.
+ */
+ public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache);
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportImpl.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.ResultSet;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportImpl implements JdbcSupport {
+ private final boolean useContextualLobCreation;
+
+ public JdbcSupportImpl(boolean useContextualLobCreation) {
+ this.useContextualLobCreation = useContextualLobCreation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LobCreator getLobCreator() {
+ return NonContextualLobCreator.INSTANCE;
+ }
+
+ public LobCreator getLobCreator(LobCreationContext lobCreationContext) {
+ if ( useContextualLobCreation ) {
+ return new ContextualLobCreator( lobCreationContext );
+ }
+ else {
+ return NonContextualLobCreator.INSTANCE;
+ }
+ }
+
+ public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache) {
+ return ResultSetWrapperProxy.generateProxy( resultSet, columnNameCache );
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/JdbcSupportLoader.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,117 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.DatabaseMetaData;
+import java.lang.reflect.Method;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Builds {@link JdbcSupport} instances based on the capabilities of the environment.
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportLoader {
+ private static final Logger log = LoggerFactory.getLogger( JdbcSupportLoader.class );
+
+ /**
+ * The public factory method for obtaining the appropriate (accoring to given JDBC {@link java.sql.Connection})
+ * {@link JdbcSupport}.
+ *
+ * @param jdbcConnection A JDBC {@link java.sql.Connection} which can be used to gauge the drivers level of support,
+ * specifically for creating LOB references.
+ *
+ * @return An appropriate {@link JdbcSupport} instance.
+ */
+ public static JdbcSupport loadJdbcSupport(Connection jdbcConnection) {
+ return new JdbcSupportImpl( useContextualLobCreation( jdbcConnection ) );
+ }
+
+ private static final Class[] NO_ARG_SIG = new Class[0];
+ private static final Object[] NO_ARGS = new Object[0];
+
+ /**
+ * Basically here we are simply checking whether we can call the {@link Connection} methods for
+ * LOB creation added in JDBC 4. We not only check whether the {@link Connection} declares these methods,
+ * but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply
+ * throwing an exception).
+ *
+ * @param jdbcConnection The connection whcih can be used in level-of-support testing.
+ *
+ * @return True if the connection can be used to create LOBs; false otherwise.
+ */
+ private static boolean useContextualLobCreation(Connection jdbcConnection) {
+ if ( jdbcConnection == null ) {
+ log.info( "Disabling contextual LOB creation as connection was null" );
+ return false;
+ }
+
+ try {
+ try {
+ DatabaseMetaData meta = jdbcConnection.getMetaData();
+ // if the jdbc driver version is less than 4, it shouldn't have createClob
+ if ( meta.getJDBCMajorVersion() < 4 ) {
+ log.info(
+ "Disabling contextual LOB creation as JDBC driver reported JDBC version [" +
+ meta.getJDBCMajorVersion() + "] less than 4"
+ );
+ return false;
+ }
+ }
+ catch ( SQLException ignore ) {
+ // ignore exception and continue
+ }
+
+ Class connectionClass = Connection.class;
+ Method createClobMethod = connectionClass.getMethod( "createClob", NO_ARG_SIG );
+ if ( createClobMethod.getDeclaringClass().equals( Connection.class ) ) {
+ // If we get here we are running in a jdk 1.6 (jdbc 4) environment...
+ // Further check to make sure the driver actually implements the LOB creation methods. We
+ // check against createClob() as indicative of all; should we check against all 3 explicitly?
+ try {
+ Object clob = createClobMethod.invoke( jdbcConnection, NO_ARGS );
+ try {
+ Method freeMethod = clob.getClass().getMethod( "free", NO_ARG_SIG );
+ freeMethod.invoke( clob, NO_ARGS );
+ }
+ catch ( Throwable ignore ) {
+ log.trace( "Unable to free CLOB created to test createClob() implementation : " + ignore );
+ }
+ return true;
+ }
+ catch ( Throwable t ) {
+ log.info( "Disabling contextual LOB creation as createClob() method threw error : " + t );
+ }
+ }
+ }
+ catch ( NoSuchMethodException ignore ) {
+ }
+
+ return false;
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreationContext.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.hibernate.JDBCException;
+import org.hibernate.exception.SQLExceptionConverter;
+
+/**
+ * Provides callback access into the context in which the LOB is to be created. Mainly this is useful
+ * for gaining access to the JDBC {@link Connection} for use in JDBC 4 environments.
+ *
+ * @author Steve Ebersole
+ */
+public interface LobCreationContext {
+ /**
+ * The callback contract for making use of the JDBC {@link Connection}.
+ */
+ public static interface Callback {
+ /**
+ * Perform whatever actions are necessary using the provided JDBC {@link Connection}.
+ *
+ * @param connection The JDBC {@link Connection}.
+ * @return The created LOB.
+ * @throws SQLException
+ */
+ public Object executeOnConnection(Connection connection) throws SQLException;
+ }
+
+ /**
+ * Execute the given callback, making sure it has access to a viable JDBC {@link Connection}.
+ *
+ * @param callback The callback to execute .
+ * @return The LOB created by the callback.
+ */
+ public Object execute(Callback callback);
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,106 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Contract for creating various LOB references.
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public interface LobCreator {
+ /**
+ * Wrap the given blob in a serializable wrapper.
+ *
+ * @param blob The blob to be wrapped.
+ * @return The wrapped blob which will be castable to {@link Blob} as well as {@link WrappedBlob}.
+ */
+ public Blob wrap(Blob blob);
+
+ /**
+ * Wrap the given clob in a serializable wrapper.
+ *
+ * @param clob The clob to be wrapped.
+ * @return The wrapped clob which will be castable to {@link Clob} as well as {@link WrappedClob}.
+ */
+ public Clob wrap(Clob clob);
+
+ /**
+ * Create a BLOB reference encapsulating the given byte array.
+ *
+ * @param bytes The byte array to wrap as a blob.
+ * @return The created blob, castable to {@link Blob} as well as {@link BlobImplementer}
+ */
+ public Blob createBlob(byte[] bytes);
+
+ /**
+ * Create a BLOB reference encapsulating the given binary stream.
+ *
+ * @param stream The binary stream to wrap as a blob.
+ * @param length The length of the stream.
+ * @return The created blob, castable to {@link Blob} as well as {@link BlobImplementer}
+ */
+ public Blob createBlob(InputStream stream, long length);
+
+ /**
+ * Create a CLOB reference encapsulating the given String data.
+ *
+ * @param string The String to wrap as a clob.
+ * @return The created clob, castable to {@link Clob} as well as {@link ClobImplementer}
+ */
+ public Clob createClob(String string);
+
+ /**
+ * Create a CLOB reference encapsulating the given character data.
+ *
+ * @param reader The character data reader.
+ * @param length The length of the reader data.
+ * @return The created clob, castable to {@link Clob} as well as {@link ClobImplementer}
+ */
+ public Clob createClob(Reader reader, long length);
+
+ /**
+ * Create a NCLOB reference encapsulating the given String data.
+ *
+ * @param string The String to wrap as a NCLOB.
+ * @return The created NCLOB, castable as {@link Clob} as well as {@link NClobImplementer}. In JDK 1.6
+ * environments, also castable to java.sql.NClob
+ */
+ public Clob createNClob(String string);
+
+ /**
+ * Create a NCLOB reference encapsulating the given character data.
+ *
+ * @param reader The character data reader.
+ * @param length The length of the reader data.
+ * @return The created NCLOB, castable as {@link Clob} as well as {@link NClobImplementer}. In JDK 1.6
+ * environments, also castable to java.sql.NClob
+ */
+ public Clob createNClob(Reader reader, long length);
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobImplementer.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,34 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+/**
+ * Marker interface for non-contextually created java.sql.NClob instances..
+ * <p/>
+ * java.sql.NClob is a new type introduced in JDK 1.6 (JDBC 4)
+ *
+ * @author Steve Ebersole
+ */
+public interface NClobImplementer extends ClobImplementer {
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NClobProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,105 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Clob;
+import java.io.Reader;
+import java.lang.reflect.Proxy;
+
+/**
+ * Manages aspects of proxying java.sql.NClobs for non-contextual creation, including proxy creation and
+ * handling proxy invocations.
+ * <p/>
+ * Generated proxies are typed as {@link java.sql.Clob} (java.sql.NClob extends {@link java.sql.Clob}) and in JDK 1.6 environments, they
+ * are also typed to java.sql.NClob
+ *
+ * @author Steve Ebersole
+ */
+public class NClobProxy extends ClobProxy {
+ public static final Class[] PROXY_INTERFACES = new Class[] { determineNClobInterface(), NClobImplementer.class };
+
+ private static Class determineNClobInterface() {
+ // java.sql.NClob is a simple marker interface extending java.sql.Clob. So if java.sql.NClob is not available
+ // on the classloader, just use java.sql.Clob
+ try {
+ return getProxyClassLoader().loadClass( "java.sql.NClob" );
+ }
+ catch ( ClassNotFoundException e ) {
+ return Clob.class;
+ }
+ }
+
+ protected NClobProxy(String string) {
+ super( string );
+ }
+
+ protected NClobProxy(Reader reader, long length) {
+ super( reader, length );
+ }
+
+ /**
+ * Generates a {@link java.sql.Clob} proxy using the string data.
+ *
+ * @param string The data to be wrapped as a {@link java.sql.Clob}.
+ *
+ * @return The generated proxy.
+ */
+ public static Clob generateProxy(String string) {
+ return ( Clob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new ClobProxy( string )
+ );
+ }
+
+ /**
+ * Generates a {@link Clob} proxy using a character reader of given length.
+ *
+ * @param reader The character reader
+ * @param length The length of the character reader
+ *
+ * @return The generated proxy.
+ */
+ public static Clob generateProxy(Reader reader, long length) {
+ return ( Clob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new ClobProxy( reader, length )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ protected static ClassLoader getProxyClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if ( cl == null ) {
+ cl = NClobImplementer.class.getClassLoader();
+ }
+ return cl;
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/NonContextualLobCreator.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,85 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * {@link LobCreator} implementation using non-contextual or local creation, meaning that we generate the LOB
+ * references ourselves as opposed to delegating to the JDBC {@link java.sql.Connection}.
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class NonContextualLobCreator extends AbstractLobCreator implements LobCreator {
+ public static final NonContextualLobCreator INSTANCE = new NonContextualLobCreator();
+
+ private NonContextualLobCreator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Blob createBlob(byte[] bytes) {
+ return BlobProxy.generateProxy( bytes );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Blob createBlob(InputStream stream, long length) {
+ return BlobProxy.generateProxy( stream, length );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createClob(String string) {
+ return ClobProxy.generateProxy( string );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createClob(Reader reader, long length) {
+ return ClobProxy.generateProxy( reader, length );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createNClob(String string) {
+ return NClobProxy.generateProxy( string );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Clob createNClob(Reader reader, long length) {
+ return NClobProxy.generateProxy( reader, length );
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ReaderInputStream.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.engine.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Exposes a {@link Reader} as an {@link InputStream}.
+ *
+ * @author Gavin King
+ */
+public class ReaderInputStream extends InputStream {
+ private Reader reader;
+
+ public ReaderInputStream(Reader reader) {
+ this.reader = reader;
+ }
+
+ public int read() throws IOException {
+ return reader.read();
+ }
+
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/ResultSetWrapperProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,194 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.util.JDBCExceptionReporter;
+
+/**
+ * A proxy for a ResultSet delegate, responsible for locally caching the columnName-to-columnIndex resolution that
+ * has been found to be inefficient in a few vendor's drivers (i.e., Oracle and Postgres).
+ *
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class ResultSetWrapperProxy implements InvocationHandler {
+ private static final Logger log = LoggerFactory.getLogger( ResultSetWrapperProxy.class );
+ private static final Class[] PROXY_INTERFACES = new Class[] { ResultSet.class };
+
+ private final ResultSet rs;
+ private final ColumnNameCache columnNameCache;
+
+ private ResultSetWrapperProxy(ResultSet rs, ColumnNameCache columnNameCache) {
+ this.rs = rs;
+ this.columnNameCache = columnNameCache;
+ }
+
+ /**
+ * Generates a proxy wrapping the ResultSet.
+ *
+ * @param resultSet The resultSet to wrap.
+ * @param columnNameCache The cache storing data for converting column names to column indexes.
+ * @return The generated proxy.
+ */
+ public static ResultSet generateProxy(ResultSet resultSet, ColumnNameCache columnNameCache) {
+ return ( ResultSet ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new ResultSetWrapperProxy( resultSet, columnNameCache )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ public static ClassLoader getProxyClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if ( cl == null ) {
+ cl = ResultSet.class.getClassLoader();
+ }
+ return cl;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if ( "findColumn".equals( method.getName() ) ) {
+ return new Integer( findColumn( ( String ) args[0] ) );
+ }
+
+ if ( isFirstArgColumnLabel( method, args ) ) {
+ try {
+ int columnIndex = findColumn( ( String ) args[0] );
+ return invokeMethod(
+ locateCorrespondingColumnIndexMethod( method ), buildColumnIndexMethodArgs( args, columnIndex )
+ );
+ }
+ catch ( SQLException ex ) {
+ StringBuffer buf = new StringBuffer()
+ .append( "Exception getting column index for column: [" )
+ .append( args[0] )
+ .append( "].\nReverting to using: [" )
+ .append( args[0] )
+ .append( "] as first argument for method: [" )
+ .append( method )
+ .append( "]" );
+ JDBCExceptionReporter.logExceptions( ex, buf.toString() );
+ }
+ catch ( NoSuchMethodException ex ) {
+ StringBuffer buf = new StringBuffer()
+ .append( "Exception switching from method: [" )
+ .append( method )
+ .append( "] to a method using the column index. Reverting to using: [" )
+ .append( method )
+ .append( "]" );
+ if ( log.isWarnEnabled() ) {
+ log.warn( buf.toString() );
+ }
+ }
+ }
+ return invokeMethod( method, args );
+ }
+
+ /**
+ * Locate the column index corresponding to the given column name via the cache.
+ *
+ * @param columnName The column name to resolve into an index.
+ * @return The column index corresponding to the given column name.
+ * @throws SQLException if the ResultSet object does not contain columnName or a database access error occurs
+ */
+ private int findColumn(String columnName) throws SQLException {
+ return columnNameCache.getIndexForColumnName( columnName, rs );
+ }
+
+ private boolean isFirstArgColumnLabel(Method method, Object args[]) {
+ // method name should start with either get or update
+ if ( ! ( method.getName().startsWith( "get" ) || method.getName().startsWith( "update" ) ) ) {
+ return false;
+ }
+
+ // method should have arguments, and have same number as incoming arguments
+ if ( ! ( method.getParameterTypes().length > 0 && args.length == method.getParameterTypes().length ) ) {
+ return false;
+ }
+
+ // The first argument should be a String (the column name)
+ //noinspection RedundantIfStatement
+ if ( ! ( String.class.isInstance( args[0] ) && method.getParameterTypes()[0].equals( String.class ) ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * For a given {@link ResultSet} method passed a column name, locate the corresponding method passed the same
+ * parameters but the column index.
+ *
+ * @param columnNameMethod The method passed the column name
+ * @return The corresponding method passed the column index.
+ * @throws NoSuchMethodException Should never happen, but...
+ */
+ private Method locateCorrespondingColumnIndexMethod(Method columnNameMethod) throws NoSuchMethodException {
+ Class actualParameterTypes[] = new Class[columnNameMethod.getParameterTypes().length];
+ actualParameterTypes[0] = int.class;
+ System.arraycopy(
+ columnNameMethod.getParameterTypes(),
+ 1,
+ actualParameterTypes,
+ 1,
+ columnNameMethod.getParameterTypes().length - 1
+ );
+ return columnNameMethod.getDeclaringClass().getMethod( columnNameMethod.getName(), actualParameterTypes );
+ }
+
+ private Object[] buildColumnIndexMethodArgs(Object[] incomingArgs, int columnIndex) {
+ Object actualArgs[] = new Object[incomingArgs.length];
+ actualArgs[0] = new Integer( columnIndex );
+ System.arraycopy( incomingArgs, 1, actualArgs, 1, incomingArgs.length - 1 );
+ return actualArgs;
+ }
+
+ private Object invokeMethod(Method method, Object args[]) throws Throwable {
+ try {
+ return method.invoke( rs, args );
+ }
+ catch ( InvocationTargetException e ) {
+ throw e.getTargetException();
+ }
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableBlobProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,112 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Blob;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Manages aspects of proxying {@link Blob Blobs} to add serializability.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class SerializableBlobProxy implements InvocationHandler, Serializable {
+ private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, WrappedBlob.class, Serializable.class };
+
+ private transient final Blob blob;
+
+ /**
+ * Builds a serializable {@link Blob} wrapper around the given {@link Blob}.
+ *
+ * @param blob The {@link Blob} to be wrapped.
+ * @see
+ */
+ private SerializableBlobProxy(Blob blob) {
+ this.blob = blob;
+ }
+
+ public Blob getWrappedBlob() {
+ if ( blob == null ) {
+ throw new IllegalStateException( "Blobs may not be accessed after serialization" );
+ }
+ else {
+ return blob;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if ( "getWrappedBlob".equals( method.getName() ) ) {
+ return getWrappedBlob();
+ }
+ try {
+ return method.invoke( getWrappedBlob(), args );
+ }
+ catch ( AbstractMethodError e ) {
+ throw new HibernateException( "The JDBC driver does not implement the method: " + method, e );
+ }
+ catch ( InvocationTargetException e ) {
+ throw e.getTargetException();
+ }
+ }
+
+ /**
+ * Generates a SerializableBlob proxy wrapping the provided Blob object.
+ *
+ * @param blob The Blob to wrap.
+ *
+ * @return The generated proxy.
+ */
+ public static Blob generateProxy(Blob blob) {
+ return ( Blob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new SerializableBlobProxy( blob )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ public static ClassLoader getProxyClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if ( cl == null ) {
+ cl = WrappedBlob.class.getClassLoader();
+ }
+ return cl;
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableClobProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,111 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.sql.Clob;
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Manages aspects of proxying {@link Clob Clobs} to add serializability.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Gail Badner
+ */
+public class SerializableClobProxy implements InvocationHandler, Serializable {
+ private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, WrappedClob.class, Serializable.class };
+
+ private transient final Clob clob;
+
+ /**
+ * Builds a serializable {@link java.sql.Clob} wrapper around the given {@link java.sql.Clob}.
+ *
+ * @param clob The {@link java.sql.Clob} to be wrapped.
+ * @see #generateProxy(java.sql.Clob)
+ */
+ protected SerializableClobProxy(Clob clob) {
+ this.clob = clob;
+ }
+
+ public Clob getWrappedClob() {
+ if ( clob == null ) {
+ throw new IllegalStateException( "Clobs may not be accessed after serialization" );
+ }
+ else {
+ return clob;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if ( "getWrappedClob".equals( method.getName() ) ) {
+ return getWrappedClob();
+ }
+ try {
+ return method.invoke( getWrappedClob(), args );
+ }
+ catch ( AbstractMethodError e ) {
+ throw new HibernateException( "The JDBC driver does not implement the method: " + method, e );
+ }
+ catch ( InvocationTargetException e ) {
+ throw e.getTargetException();
+ }
+ }
+
+ /**
+ * Generates a SerializableClobProxy proxy wrapping the provided Clob object.
+ *
+ * @param clob The Clob to wrap.
+ * @return The generated proxy.
+ */
+ public static Clob generateProxy(Clob clob) {
+ return ( Clob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new SerializableClobProxy( clob )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ public static ClassLoader getProxyClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if ( cl == null ) {
+ cl = WrappedClob.class.getClassLoader();
+ }
+ return cl;
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/SerializableNClobProxy.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,92 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Clob;
+import java.lang.reflect.Proxy;
+
+/**
+ * Manages aspects of proxying java.sql.NClobs to add serializability.
+ *
+ * @author Steve Ebersole
+ */
+public class SerializableNClobProxy extends SerializableClobProxy {
+ private static final Class NCLOB_CLASS = loadNClobClassIfAvailable();
+
+ private static Class loadNClobClassIfAvailable() {
+ try {
+ return getProxyClassLoader().loadClass( "java.sql.NClob" );
+ }
+ catch ( ClassNotFoundException e ) {
+ return null;
+ }
+ }
+
+ private static final Class[] PROXY_INTERFACES = new Class[] { determineNClobInterface(), WrappedClob.class };
+
+ private static Class determineNClobInterface() {
+ // java.sql.NClob is a simple marker interface extending java.sql.Clob. So if java.sql.NClob is not available
+ // on the classloader, just use java.sql.Clob
+ return NCLOB_CLASS == null ? Clob.class : NCLOB_CLASS;
+ }
+
+ public static boolean isNClob(Clob clob) {
+ return NCLOB_CLASS != null && NCLOB_CLASS.isInstance( clob );
+ }
+
+ /**
+ * Builds a serializable {@link java.sql.Clob} wrapper around the given {@link java.sql.Clob}.
+ *
+ * @param clob The {@link java.sql.Clob} to be wrapped.
+ *
+ * @see #generateProxy(java.sql.Clob)
+ */
+ protected SerializableNClobProxy(Clob clob) {
+ super( clob );
+ }
+
+ /**
+ * Generates a SerializableClobProxy proxy wrapping the provided Clob object.
+ *
+ * @param clob The Clob to wrap.
+ * @return The generated proxy.
+ */
+ public static Clob generateProxy(Clob clob) {
+ return ( Clob ) Proxy.newProxyInstance(
+ getProxyClassLoader(),
+ PROXY_INTERFACES,
+ new SerializableNClobProxy( clob )
+ );
+ }
+
+ /**
+ * Determines the appropriate class loader to which the generated proxy
+ * should be scoped.
+ *
+ * @return The class loader appropriate for proxy construction.
+ */
+ public static ClassLoader getProxyClassLoader() {
+ return SerializableClobProxy.getProxyClassLoader();
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/StreamUtils.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,71 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * Stream copying utilities
+ *
+ * @author Steve Ebersole
+ */
+public class StreamUtils {
+ public static final int DEFAULT_CHUNK_SIZE = 1024;
+
+ public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException {
+ return copy( inputStream, outputStream, DEFAULT_CHUNK_SIZE );
+ }
+
+ public static long copy(InputStream inputStream, OutputStream outputStream, int bufferSize) throws IOException {
+ byte[] buffer = new byte[bufferSize];
+ long count = 0;
+ int n;
+ while ( -1 != ( n = inputStream.read( buffer ) ) ) {
+ outputStream.write( buffer, 0, n );
+ count += n;
+ }
+ return count;
+
+ }
+
+ public static long copy(Reader reader, Writer writer) throws IOException {
+ return copy( reader, writer, DEFAULT_CHUNK_SIZE );
+ }
+
+ public static long copy(Reader reader, Writer writer, int bufferSize) throws IOException {
+ char[] buffer = new char[bufferSize];
+ long count = 0;
+ int n;
+ while ( -1 != ( n = reader.read( buffer ) ) ) {
+ writer.write( buffer, 0, n );
+ count += n;
+ }
+ return count;
+
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedBlob.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Blob;
+
+/**
+ * Contract for {@link Blob} wrappers.
+ *
+ * @author Steve Ebersole
+ */
+public interface WrappedBlob {
+ /**
+ * Retrieve the wrapped {@link Blob} reference
+ *
+ * @return The wrapped {@link Blob} reference
+ */
+ public Blob getWrappedBlob();
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/engine/jdbc/WrappedClob.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc;
+
+import java.sql.Clob;
+
+/**
+ * Contract for {@link Clob} wrappers.
+ *
+ * @author Steve Ebersole
+ */
+public interface WrappedClob {
+ /**
+ * Retrieve the wrapped {@link java.sql.Blob} reference
+ *
+ * @return The wrapped {@link java.sql.Blob} reference
+ */
+ public Clob getWrappedClob();
+}
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/impl/SessionImpl.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -76,6 +76,8 @@
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.StatefulPersistenceContext;
import org.hibernate.engine.Status;
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreationContext.Callback;
import org.hibernate.engine.query.FilterQueryPlan;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan;
@@ -139,7 +141,7 @@
* @author Gavin King
*/
public final class SessionImpl extends AbstractSessionImpl
- implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
+ implements EventSource, org.hibernate.classic.Session, JDBCContext.Context, LobCreationContext {
// todo : need to find a clean way to handle the "event source" role
// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
@@ -1979,7 +1981,22 @@
oos.writeObject( enabledFilters );
oos.writeObject( childSessionsByEntityMode );
}
-
+ public Object execute(Callback callback) {
+ Connection connection = jdbcContext.getConnectionManager().getConnection();
+ try {
+ return callback.executeOnConnection( connection );
+ }
+ catch ( SQLException e ) {
+ throw JDBCExceptionHelper.convert(
+ getFactory().getSQLExceptionConverter(),
+ e,
+ "Error creating contextual LOB : " + e.getMessage()
+ );
+ }
+ finally {
+ jdbcContext.getConnectionManager().afterStatement();
+ }
+ }
private class CoordinatingEntityNameResolver implements EntityNameResolver {
public String resolveEntityName(Object entity) {
String entityName = interceptor.getEntityName( entity );
Deleted: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -1,56 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.jdbc;
-
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Implementation of ColumnNameCache.
- *
- * @author Steve Ebersole
- */
-public class ColumnNameCache {
-
- private final Map columnNameToIndexCache;
-
- public ColumnNameCache(int columnCount) {
- // should *not* need to grow beyond the size of the total number of columns in the rs
- this.columnNameToIndexCache = new HashMap( columnCount );
- }
-
- public int getIndexForColumnName(String columnName, ResultSetWrapper rs)throws SQLException {
- Integer cached = ( Integer ) columnNameToIndexCache.get( columnName );
- if ( cached != null ) {
- return cached.intValue();
- }
- else {
- int index = rs.getTarget().findColumn( columnName );
- columnNameToIndexCache.put( columnName, new Integer(index) );
- return index;
- }
- }
-}
Deleted: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -1,642 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Map;
-
-/**
- * A ResultSet delegate, responsible for locally caching the columnName-to-columnIndex
- * resolution that has been found to be inefficient in a few vendor's drivers (i.e., Oracle
- * and Postgres).
- *
- * @author Steve Ebersole
- */
-public class ResultSetWrapper implements ResultSet {
-
- private ResultSet rs;
- private ColumnNameCache columnNameCache;
-
- public ResultSetWrapper(ResultSet resultSet, ColumnNameCache columnNameCache) {
- this.rs = resultSet;
- this.columnNameCache = columnNameCache;
- }
-
- /*package*/ ResultSet getTarget() {
- return rs;
- }
-
-
- // ResultSet impl ("overridden") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- /**
- * Overridden version to utilize local caching of the column indexes by name
- * to improve performance for those drivers which are known to not support
- * such caching by themselves.
- * <p/>
- * This implementation performs the caching based on the upper case version
- * of the given column name.
- *
- * @param columnName The column name to resolve into an index.
- * @return The column index corresponding to the given column name.
- * @throws SQLException - if the ResultSet object does not contain
- * columnName or a database access error occurs
- */
- public int findColumn(String columnName) throws SQLException {
- return columnNameCache.getIndexForColumnName( columnName, this );
- }
-
- public Array getArray(String colName) throws SQLException {
- return rs.getArray( findColumn(colName) );
- }
-
- public void updateArray(String columnName, Array x) throws SQLException {
- rs.updateArray( findColumn(columnName), x );
- }
-
- public InputStream getAsciiStream(String columnName) throws SQLException {
- return rs.getAsciiStream( findColumn(columnName) );
- }
-
- public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException {
- rs.updateAsciiStream( findColumn(columnName), x, length );
- }
-
- public BigDecimal getBigDecimal(String columnName) throws SQLException {
- return rs.getBigDecimal( findColumn(columnName) );
- }
-
- public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
- return rs.getBigDecimal( findColumn(columnName), scale );
- }
-
- public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
- rs.updateBigDecimal( findColumn(columnName), x );
- }
-
- public InputStream getBinaryStream(String columnName) throws SQLException {
- return rs.getBinaryStream( findColumn(columnName) );
- }
-
- public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException {
- rs.updateBinaryStream( findColumn(columnName), x, length );
- }
-
- public Blob getBlob(String columnName) throws SQLException {
- return rs.getBlob( findColumn(columnName) );
- }
-
- public void updateBlob(String columnName, Blob x) throws SQLException {
- rs.updateBlob( findColumn(columnName), x );
- }
-
- public boolean getBoolean(String columnName) throws SQLException {
- return rs.getBoolean( findColumn(columnName) );
- }
-
- public void updateBoolean(String columnName, boolean x) throws SQLException {
- rs.updateBoolean( findColumn(columnName), x );
- }
-
- public byte getByte(String columnName) throws SQLException {
- return rs.getByte( findColumn(columnName) );
- }
-
- public void updateByte(String columnName, byte x) throws SQLException {
- rs.updateByte( findColumn(columnName), x );
- }
-
- public byte[] getBytes(String columnName) throws SQLException {
- return rs.getBytes( findColumn(columnName) );
- }
-
- public void updateBytes(String columnName, byte[] x) throws SQLException {
- rs.updateBytes( findColumn(columnName), x );
- }
-
- public Reader getCharacterStream(String columnName) throws SQLException {
- return rs.getCharacterStream( findColumn(columnName) );
- }
-
- public void updateCharacterStream(String columnName, Reader x, int length) throws SQLException {
- rs.updateCharacterStream( findColumn(columnName), x, length );
- }
-
- public Clob getClob(String columnName) throws SQLException {
- return rs.getClob( findColumn(columnName) );
- }
-
- public void updateClob(String columnName, Clob x) throws SQLException {
- rs.updateClob( findColumn(columnName), x );
- }
-
- public Date getDate(String columnName) throws SQLException {
- return rs.getDate( findColumn(columnName) );
- }
-
- public Date getDate(String columnName, Calendar cal) throws SQLException {
- return rs.getDate( findColumn(columnName), cal );
- }
-
- public void updateDate(String columnName, Date x) throws SQLException {
- rs.updateDate( findColumn(columnName), x );
- }
-
- public double getDouble(String columnName) throws SQLException {
- return rs.getDouble( findColumn(columnName) );
- }
-
- public void updateDouble(String columnName, double x) throws SQLException {
- rs.updateDouble( findColumn(columnName), x );
- }
-
- public float getFloat(String columnName) throws SQLException {
- return rs.getFloat( findColumn(columnName) );
- }
-
- public void updateFloat(String columnName, float x) throws SQLException {
- rs.updateFloat( findColumn(columnName), x );
- }
-
- public int getInt(String columnName) throws SQLException {
- return rs.getInt( findColumn(columnName) );
- }
-
- public void updateInt(String columnName, int x) throws SQLException {
- rs.updateInt( findColumn(columnName), x );
- }
-
- public long getLong(String columnName) throws SQLException {
- return rs.getLong( findColumn(columnName) );
- }
-
- public void updateLong(String columnName, long x) throws SQLException {
- rs.updateLong( findColumn(columnName), x );
- }
-
- public Object getObject(String columnName) throws SQLException {
- return rs.getObject( findColumn(columnName) );
- }
-
- public Object getObject(String columnName, Map map) throws SQLException {
- return rs.getObject( findColumn(columnName), map );
- }
-
- public void updateObject(String columnName, Object x) throws SQLException {
- rs.updateObject( findColumn(columnName), x );
- }
-
- public void updateObject(String columnName, Object x, int scale) throws SQLException {
- rs.updateObject( findColumn(columnName), x, scale );
- }
-
- public Ref getRef(String columnName) throws SQLException {
- return rs.getRef( findColumn(columnName) );
- }
-
- public void updateRef(String columnName, Ref x) throws SQLException {
- rs.updateRef( findColumn(columnName), x );
- }
-
- public short getShort(String columnName) throws SQLException {
- return rs.getShort( findColumn(columnName) );
- }
-
- public void updateShort(String columnName, short x) throws SQLException {
- rs.updateShort( findColumn(columnName), x );
- }
-
- public String getString(String columnName) throws SQLException {
- return rs.getString( findColumn(columnName) );
- }
-
- public void updateString(String columnName, String x) throws SQLException {
- rs.updateString( findColumn(columnName), x );
- }
-
- public Time getTime(String columnName) throws SQLException {
- return rs.getTime( findColumn(columnName) );
- }
-
- public Time getTime(String columnName, Calendar cal) throws SQLException {
- return rs.getTime( findColumn(columnName), cal );
- }
-
- public void updateTime(String columnName, Time x) throws SQLException {
- rs.updateTime( findColumn(columnName), x );
- }
-
- public Timestamp getTimestamp(String columnName) throws SQLException {
- return rs.getTimestamp( findColumn(columnName) );
- }
-
- public void updateTimestamp(String columnName, Timestamp x) throws SQLException {
- rs.updateTimestamp( findColumn(columnName), x );
- }
-
- public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
- return rs.getTimestamp( findColumn(columnName), cal );
- }
-
- public InputStream getUnicodeStream(String columnName) throws SQLException {
- return rs.getUnicodeStream( findColumn(columnName) );
- }
-
- public URL getURL(String columnName) throws SQLException {
- return rs.getURL( findColumn(columnName) );
- }
-
- public void updateNull(String columnName) throws SQLException {
- rs.updateNull( findColumn(columnName) );
- }
-
-
- // ResultSet impl (delegated) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- public int getConcurrency() throws SQLException {
- return rs.getConcurrency();
- }
-
- public int getFetchDirection() throws SQLException {
- return rs.getFetchDirection();
- }
-
- public int getFetchSize() throws SQLException {
- return rs.getFetchSize();
- }
-
- public int getRow() throws SQLException {
- return rs.getRow();
- }
-
- public int getType() throws SQLException {
- return rs.getType();
- }
-
- public void afterLast() throws SQLException {
- rs.afterLast();
- }
-
- public void beforeFirst() throws SQLException {
- rs.beforeFirst();
- }
-
- public void cancelRowUpdates() throws SQLException {
- rs.cancelRowUpdates();
- }
-
- public void clearWarnings() throws SQLException {
- rs.clearWarnings();
- }
-
- public void close() throws SQLException {
- rs.close();
- }
-
- public void deleteRow() throws SQLException {
- rs.deleteRow();
- }
-
- public void insertRow() throws SQLException {
- rs.insertRow();
- }
-
- public void moveToCurrentRow() throws SQLException {
- rs.moveToCurrentRow();
- }
-
- public void moveToInsertRow() throws SQLException {
- rs.moveToInsertRow();
- }
-
- public void refreshRow() throws SQLException {
- rs.refreshRow();
- }
-
- public void updateRow() throws SQLException {
- rs.updateRow();
- }
-
- public boolean first() throws SQLException {
- return rs.first();
- }
-
- public boolean isAfterLast() throws SQLException {
- return rs.isAfterLast();
- }
-
- public boolean isBeforeFirst() throws SQLException {
- return rs.isBeforeFirst();
- }
-
- public boolean isFirst() throws SQLException {
- return rs.isFirst();
- }
-
- public boolean isLast() throws SQLException {
- return rs.isLast();
- }
-
- public boolean last() throws SQLException {
- return rs.last();
- }
-
- public boolean next() throws SQLException {
- return rs.next();
- }
-
- public boolean previous() throws SQLException {
- return rs.previous();
- }
-
- public boolean rowDeleted() throws SQLException {
- return rs.rowDeleted();
- }
-
- public boolean rowInserted() throws SQLException {
- return rs.rowInserted();
- }
-
- public boolean rowUpdated() throws SQLException {
- return rs.rowUpdated();
- }
-
- public boolean wasNull() throws SQLException {
- return rs.wasNull();
- }
-
- public byte getByte(int columnIndex) throws SQLException {
- return rs.getByte(columnIndex);
- }
-
- public double getDouble(int columnIndex) throws SQLException {
- return rs.getDouble(columnIndex);
- }
-
- public float getFloat(int columnIndex) throws SQLException {
- return rs.getFloat(columnIndex);
- }
-
- public int getInt(int columnIndex) throws SQLException {
- return rs.getInt(columnIndex);
- }
-
- public long getLong(int columnIndex) throws SQLException {
- return rs.getLong(columnIndex);
- }
-
- public short getShort(int columnIndex) throws SQLException {
- return rs.getShort(columnIndex);
- }
-
- public void setFetchDirection(int direction) throws SQLException {
- rs.setFetchDirection(direction);
- }
-
- public void setFetchSize(int rows) throws SQLException {
- rs.setFetchSize(rows);
- }
-
- public void updateNull(int columnIndex) throws SQLException {
- rs.updateNull(columnIndex);
- }
-
- public boolean absolute(int row) throws SQLException {
- return rs.absolute(row);
- }
-
- public boolean getBoolean(int columnIndex) throws SQLException {
- return rs.getBoolean(columnIndex);
- }
-
- public boolean relative(int rows) throws SQLException {
- return rs.relative(rows);
- }
-
- public byte[] getBytes(int columnIndex) throws SQLException {
- return rs.getBytes(columnIndex);
- }
-
- public void updateByte(int columnIndex, byte x) throws SQLException {
- rs.updateByte(columnIndex, x);
- }
-
- public void updateDouble(int columnIndex, double x) throws SQLException {
- rs.updateDouble(columnIndex, x);
- }
-
- public void updateFloat(int columnIndex, float x) throws SQLException {
- rs.updateFloat(columnIndex, x);
- }
-
- public void updateInt(int columnIndex, int x) throws SQLException {
- rs.updateInt(columnIndex, x);
- }
-
- public void updateLong(int columnIndex, long x) throws SQLException {
- rs.updateLong(columnIndex, x);
- }
-
- public void updateShort(int columnIndex, short x) throws SQLException {
- rs.updateShort(columnIndex, x);
- }
-
- public void updateBoolean(int columnIndex, boolean x) throws SQLException {
- rs.updateBoolean(columnIndex, x);
- }
-
- public void updateBytes(int columnIndex, byte[] x) throws SQLException {
- rs.updateBytes(columnIndex, x);
- }
-
- public InputStream getAsciiStream(int columnIndex) throws SQLException {
- return rs.getAsciiStream(columnIndex);
- }
-
- public InputStream getBinaryStream(int columnIndex) throws SQLException {
- return rs.getBinaryStream(columnIndex);
- }
-
- public InputStream getUnicodeStream(int columnIndex) throws SQLException {
- return rs.getUnicodeStream(columnIndex);
- }
-
- public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
- rs.updateAsciiStream(columnIndex, x, length);
- }
-
- public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
- rs.updateBinaryStream(columnIndex, x, length);
- }
-
- public Reader getCharacterStream(int columnIndex) throws SQLException {
- return rs.getCharacterStream(columnIndex);
- }
-
- public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
- rs.updateCharacterStream(columnIndex, x, length);
- }
-
- public Object getObject(int columnIndex) throws SQLException {
- return rs.getObject(columnIndex);
- }
-
- public void updateObject(int columnIndex, Object x) throws SQLException {
- rs.updateObject(columnIndex, x);
- }
-
- public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
- rs.updateObject(columnIndex, x, scale);
- }
-
- public String getCursorName() throws SQLException {
- return rs.getCursorName();
- }
-
- public String getString(int columnIndex) throws SQLException {
- return rs.getString(columnIndex);
- }
-
- public void updateString(int columnIndex, String x) throws SQLException {
- rs.updateString(columnIndex, x);
- }
-
- public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
- return rs.getBigDecimal(columnIndex);
- }
-
- public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
- return rs.getBigDecimal(columnIndex, scale);
- }
-
- public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
- rs.updateBigDecimal(columnIndex, x);
- }
-
- public URL getURL(int columnIndex) throws SQLException {
- return rs.getURL(columnIndex);
- }
-
- public Array getArray(int columnIndex) throws SQLException {
- return rs.getArray(columnIndex);
- }
-
- public void updateArray(int columnIndex, Array x) throws SQLException {
- rs.updateArray(columnIndex, x);
- }
-
- public Blob getBlob(int columnIndex) throws SQLException {
- return rs.getBlob(columnIndex);
- }
-
- public void updateBlob(int columnIndex, Blob x) throws SQLException {
- rs.updateBlob(columnIndex, x);
- }
-
- public Clob getClob(int columnIndex) throws SQLException {
- return rs.getClob(columnIndex);
- }
-
- public void updateClob(int columnIndex, Clob x) throws SQLException {
- rs.updateClob(columnIndex, x);
- }
-
- public Date getDate(int columnIndex) throws SQLException {
- return rs.getDate(columnIndex);
- }
-
- public void updateDate(int columnIndex, Date x) throws SQLException {
- rs.updateDate(columnIndex, x);
- }
-
- public Ref getRef(int columnIndex) throws SQLException {
- return rs.getRef(columnIndex);
- }
-
- public void updateRef(int columnIndex, Ref x) throws SQLException {
- rs.updateRef(columnIndex, x);
- }
-
- public ResultSetMetaData getMetaData() throws SQLException {
- return rs.getMetaData();
- }
-
- public SQLWarning getWarnings() throws SQLException {
- return rs.getWarnings();
- }
-
- public Statement getStatement() throws SQLException {
- return rs.getStatement();
- }
-
- public Time getTime(int columnIndex) throws SQLException {
- return rs.getTime(columnIndex);
- }
-
- public void updateTime(int columnIndex, Time x) throws SQLException {
- rs.updateTime(columnIndex, x);
- }
-
- public Timestamp getTimestamp(int columnIndex) throws SQLException {
- return rs.getTimestamp(columnIndex);
- }
-
- public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
- rs.updateTimestamp(columnIndex, x);
- }
-
- public Object getObject(int columnIndex, Map map) throws SQLException {
- return rs.getObject( columnIndex, map );
- }
-
- public Date getDate(int columnIndex, Calendar cal) throws SQLException {
- return rs.getDate(columnIndex, cal);
- }
-
- public Time getTime(int columnIndex, Calendar cal) throws SQLException {
- return rs.getTime(columnIndex, cal);
- }
-
- public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
- return rs.getTimestamp(columnIndex, cal);
- }
-}
-
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/loader/Loader.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -63,6 +63,7 @@
import org.hibernate.engine.SubselectFetch;
import org.hibernate.engine.TwoPhaseLoad;
import org.hibernate.engine.TypedValue;
+import org.hibernate.engine.jdbc.ColumnNameCache;
import org.hibernate.event.EventSource;
import org.hibernate.event.PostLoadEvent;
import org.hibernate.event.PreLoadEvent;
@@ -70,8 +71,6 @@
import org.hibernate.hql.HolderInstantiator;
import org.hibernate.impl.FetchingScrollableResultsImpl;
import org.hibernate.impl.ScrollableResultsImpl;
-import org.hibernate.jdbc.ColumnNameCache;
-import org.hibernate.jdbc.ResultSetWrapper;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
@@ -1839,7 +1838,9 @@
if ( session.getFactory().getSettings().isWrapResultSetsEnabled() ) {
try {
log.debug("Wrapping result set [" + rs + "]");
- return new ResultSetWrapper( rs, retreiveColumnNameToIndexCache( rs ) );
+ return session.getFactory()
+ .getSettings()
+ .getJdbcSupport().wrap( rs, retreiveColumnNameToIndexCache( rs ) );
}
catch(SQLException e) {
log.info("Error wrapping result set", e);
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/BlobType.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -36,11 +36,14 @@
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
-import org.hibernate.lob.SerializableBlob;
+import org.hibernate.engine.jdbc.BlobImplementer;
+import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.util.ArrayHelper;
/**
@@ -48,135 +51,223 @@
* @author Gavin King
*/
public class BlobType extends AbstractType {
+ /**
+ * {@inheritDoc}
+ */
+ public void nullSafeSet(
+ PreparedStatement st,
+ Object value,
+ int index,
+ boolean[] settable,
+ SessionImplementor session) throws HibernateException, SQLException {
+ if ( settable[0] ) {
+ set( st, value, index, session );
+ }
+ }
- public void set(PreparedStatement st, Object value, int index, SessionImplementor session)
- throws HibernateException, SQLException {
-
- if (value==null) {
- st.setNull(index, Types.BLOB);
+ /**
+ * {@inheritDoc}
+ */
+ public void nullSafeSet(
+ PreparedStatement st,
+ Object value,
+ int index,
+ SessionImplementor session) throws HibernateException, SQLException {
+ set( st, value, index, session );
+ }
+
+ public void set(
+ PreparedStatement st,
+ Object value,
+ int index,
+ SessionImplementor session) throws HibernateException, SQLException {
+ if ( value == null ) {
+ st.setNull( index, Types.BLOB );
+ return;
}
+
+ Blob blob = ( Blob ) value;
+
+ if ( WrappedBlob.class.isInstance( blob ) ) {
+ blob = ( (WrappedBlob) value ).getWrappedBlob();
+ }
+
+ final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob()
+ && BlobImplementer.class.isInstance( blob );
+
+ if ( useInputStream ) {
+ st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() );
+ }
else {
-
- if (value instanceof SerializableBlob) {
- value = ( (SerializableBlob) value ).getWrappedBlob();
- }
-
- final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob() &&
- (value instanceof BlobImpl);
-
- if ( useInputStream ) {
- BlobImpl blob = (BlobImpl) value;
- st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() );
- }
- else {
- st.setBlob(index, (Blob) value);
- }
-
+ st.setBlob( index, blob );
}
-
}
- public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
- Blob value = rs.getBlob(name);
- return rs.wasNull() ? null : new SerializableBlob(value);
+ /**
+ * {@inheritDoc}
+ */
+ public Object nullSafeGet(
+ ResultSet rs,
+ String name,
+ SessionImplementor session,
+ Object owner) throws HibernateException, SQLException {
+ return get( rs, name, Hibernate.getLobCreator( session ) );
}
+ /**
+ * {@inheritDoc}
+ */
+ public Object nullSafeGet(
+ ResultSet rs,
+ String[] names,
+ SessionImplementor session,
+ Object owner) throws HibernateException, SQLException {
+ return get( rs, names[0], Hibernate.getLobCreator( session ) );
+ }
+
+ /**
+ * A method to extract the BLOB value from a result set.
+ *
+ * @param rs The result set
+ * @param name The name of the column containing the BLOB
+ *
+ * @return The BLOB
+ *
+ * @throws SQLException Indicates a problem accessing the result set
+ *
+ * @deprecated Use {@link #get(ResultSet,String,LobCreator)} instead
+ */
+ public Object get(ResultSet rs, String name) throws SQLException {
+ return get( rs, name, NonContextualLobCreator.INSTANCE );
+ }
+
+ public Object get(ResultSet rs, String name, LobCreator lobCreator) throws SQLException {
+ Blob value = rs.getBlob( name );
+ return rs.wasNull() ? null : lobCreator.wrap( value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public Class getReturnedClass() {
return Blob.class;
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isEqual(Object x, Object y, EntityMode entityMode) {
return x == y;
}
+ /**
+ * {@inheritDoc}
+ */
public int getHashCode(Object x, EntityMode entityMode) {
return System.identityHashCode(x);
}
+ /**
+ * {@inheritDoc}
+ */
public int compare(Object x, Object y, EntityMode entityMode) {
return 0; //lobs cannot be compared
}
+ /**
+ * {@inheritDoc}
+ */
public String getName() {
return "blob";
}
-
+
+ /**
+ * {@inheritDoc}
+ */
public Serializable disassemble(Object value, SessionImplementor session, Object owner)
- throws HibernateException {
+ throws UnsupportedOperationException {
throw new UnsupportedOperationException("Blobs are not cacheable");
}
+ /**
+ * {@inheritDoc}
+ */
public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) {
return value;
}
+ /**
+ * {@inheritDoc}
+ */
public Object fromXMLNode(Node xml, Mapping factory) {
throw new UnsupportedOperationException("todo");
}
+ /**
+ * {@inheritDoc}
+ */
public int getColumnSpan(Mapping mapping) {
return 1;
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isMutable() {
return false;
}
- public Object nullSafeGet(ResultSet rs, String name,
- SessionImplementor session, Object owner)
- throws HibernateException, SQLException {
- return get(rs, name);
- }
-
- public Object nullSafeGet(ResultSet rs, String[] names,
- SessionImplementor session, Object owner)
- throws HibernateException, SQLException {
- return get( rs, names[0] );
- }
-
- public void nullSafeSet(PreparedStatement st, Object value, int index,
- boolean[] settable, SessionImplementor session)
- throws HibernateException, SQLException {
- if ( settable[0] ) set(st, value, index, session);
- }
-
- public void nullSafeSet(PreparedStatement st, Object value, int index,
- SessionImplementor session) throws HibernateException, SQLException {
- set(st, value, index, session);
- }
-
- public Object replace(Object original, Object target,
- SessionImplementor session, Object owner, Map copyCache)
- throws HibernateException {
+ /**
+ * {@inheritDoc}
+ */
+ public Object replace(
+ Object original,
+ Object target,
+ SessionImplementor session,
+ Object owner,
+ Map copyCache) throws HibernateException {
//Blobs are ignored by merge()
return target;
}
-
+
+ /**
+ * {@inheritDoc}
+ */
public int[] sqlTypes(Mapping mapping) throws MappingException {
return new int[] { Types.BLOB };
}
+ /**
+ * {@inheritDoc}
+ */
public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) {
throw new UnsupportedOperationException("todo");
}
- public String toLoggableString(Object value, SessionFactoryImplementor factory)
- throws HibernateException {
+ /**
+ * {@inheritDoc}
+ */
+ public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
return value==null ? "null" : value.toString();
}
-
+
+ /**
+ * {@inheritDoc}
+ */
public boolean[] toColumnNullness(Object value, Mapping mapping) {
return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
}
- public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isDirty(
+ Object old,
+ Object current,
+ boolean[] checkable,
+ SessionImplementor session) throws HibernateException {
return checkable[0] && isDirty(old, current, session);
}
}
-
-
-
-
-
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java 2010-04-27 07:07:12 UTC (rev 19299)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ClobType.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -40,8 +40,10 @@
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.ClobImpl;
-import org.hibernate.lob.SerializableClob;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
+import org.hibernate.engine.jdbc.WrappedClob;
+import org.hibernate.engine.jdbc.ClobImplementer;
import org.hibernate.util.ArrayHelper;
/**
@@ -50,38 +52,89 @@
*/
public class ClobType extends AbstractType {
- public void set(PreparedStatement st, Object value, int index, SessionImplementor session)
- throws HibernateException, SQLException {
-
- if (value==null) {
- st.setNull(index, Types.CLOB);
+ public void nullSafeSet(
+ PreparedStatement st,
+ Object value,
+ int index,
+ boolean[] settable,
+ SessionImplementor session) throws SQLException {
+ if ( settable[0] ) {
+ set( st, value, index, session );
}
+ }
+
+ public void nullSafeSet(
+ PreparedStatement st,
+ Object value,
+ int index,
+ SessionImplementor session) throws SQLException {
+ set( st, value, index, session );
+ }
+
+ public void set(
+ PreparedStatement st,
+ Object value,
+ int index,
+ SessionImplementor session) throws SQLException {
+ if ( value == null ) {
+ st.setNull( index, Types.CLOB );
+ return;
+ }
+
+ Clob clob = ( Clob ) value;
+
+ if ( WrappedClob.class.isInstance( clob ) ) {
+ clob = ( (WrappedClob) value ).getWrappedClob();
+ }
+
+ final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob()
+ && ClobImplementer.class.isInstance( clob );
+
+ if ( useInputStream ) {
+ st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() );
+ }
else {
-
- if (value instanceof SerializableClob) {
- value = ( (SerializableClob) value ).getWrappedClob();
- }
-
- final boolean useReader = session.getFactory().getDialect().useInputStreamToInsertBlob() &&
- (value instanceof ClobImpl);
-
- if ( useReader ) {
- ClobImpl clob = (ClobImpl) value;
- st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() );
- }
- else {
- st.setClob(index, (Clob) value);
- }
-
+ st.setClob( index, clob );
}
-
}
- public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
- Clob value = rs.getClob(name);
- return rs.wasNull() ? null : new SerializableClob(value);
+ public Object nullSafeGet(
+ ResultSet rs,
+ String name,
+ SessionImplementor session,
+ Object owner) throws SQLException {
+ return get( rs, name, Hibernate.getLobCreator( session ) );
}
+ public Object nullSafeGet(
+ ResultSet rs,
+ String[] names,
+ SessionImplementor session,
+ Object owner) throws SQLException {
+ return get( rs, names[0], Hibernate.getLobCreator( session ) );
+ }
+
+ /**
+ * A method to extract the CLOB value from a result set.
+ *
+ * @param rs The result set
+ * @param name The name of the column containing the CLOB
+ *
+ * @return The CLOB
+ *
+ * @throws SQLException Indicates a problem accessing the result set
+ *
+ * @deprecated Use {@link #get(ResultSet,String,LobCreator)} instead
+ */
+ public Object get(ResultSet rs, String name) throws SQLException {
+ return get( rs, name, NonContextualLobCreator.INSTANCE );
+ }
+
+ public Clob get(ResultSet rs, String name, LobCreator lobCreator) throws SQLException {
+ Clob value = rs.getClob( name );
+ return rs.wasNull() ? null : lobCreator.wrap( value );
+ }
+
public Class getReturnedClass() {
return Clob.class;
}
@@ -123,29 +176,6 @@
return false;
}
- public Object nullSafeGet(ResultSet rs, String name,
- SessionImplementor session, Object owner)
- throws HibernateException, SQLException {
- return get(rs, name);
- }
-
- public Object nullSafeGet(ResultSet rs, String[] names,
- SessionImplementor session, Object owner)
- throws HibernateException, SQLException {
- return get( rs, names[0] );
- }
-
- public void nullSafeSet(PreparedStatement st, Object value, int index,
- boolean[] settable, SessionImplementor session)
- throws HibernateException, SQLException {
- if ( settable[0] ) set(st, value, index, session);
- }
-
- public void nullSafeSet(PreparedStatement st, Object value, int index,
- SessionImplementor session) throws HibernateException, SQLException {
- set(st, value, index, session);
- }
-
public Object replace(Object original, Object target,
SessionImplementor session, Object owner, Map copyCache)
throws HibernateException {
Added: core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/pom.xml 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ ~ third-party contributors as indicated by either @author tags or express
+ ~ copyright attribution statements applied by the authors. All
+ ~ third-party contributions are distributed under license by Red Hat Inc.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-parent</artifactId>
+ <version>3.3.2.GA_CP01</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>hibernate-jdbc3-testing</artifactId>
+ <packaging>jar</packaging>
+
+ <name>Hibernate JDBC3-JdbcSupport Testing</name>
+ <description>Test support of JDBC3 through JdbcSupport</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added: core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/java/org/hibernate/engine/jdbc/jdbc3/JdbcSupportTest.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc.jdbc3;
+
+import java.sql.SQLException;
+import java.sql.Blob;
+import java.sql.Clob;
+
+import junit.framework.TestCase;
+
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
+import org.hibernate.engine.jdbc.BlobImplementer;
+import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.engine.jdbc.WrappedClob;
+import org.hibernate.engine.jdbc.ClobImplementer;
+import org.hibernate.engine.jdbc.NClobImplementer;
+
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportTest extends TestCase {
+ public void testLobCreator() throws ClassNotFoundException, SQLException {
+ final LobCreationContext lobCreationContext = new LobCreationContext() {
+ public Object execute(Callback callback) {
+ fail( "Unexpeted call to getConnection" );
+ return null;
+ }
+ };
+
+ LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( null ).getLobCreator( lobCreationContext );
+
+ Blob blob = lobCreator.createBlob( new byte[] {} );
+ assertTrue( blob instanceof BlobImplementer );
+ blob = lobCreator.wrap( blob );
+ assertTrue( blob instanceof WrappedBlob );
+
+ Clob clob = lobCreator.createClob( "Hi" );
+ assertTrue( clob instanceof ClobImplementer );
+ clob = lobCreator.wrap( clob );
+ assertTrue( clob instanceof WrappedClob );
+
+ Clob nclob = lobCreator.createNClob( "Hi" );
+ assertTrue( nclob instanceof NClobImplementer );
+ nclob = lobCreator.wrap( nclob );
+ assertTrue( nclob instanceof WrappedClob );
+
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc3-testing/src/test/resources/log4j.properties 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,30 @@
+#
+# Hibernate, Relational Persistence for Idiomatic Java
+#
+# Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+# third-party contributors as indicated by either @author tags or express
+# copyright attribution statements applied by the authors. All
+# third-party contributions are distributed under license by Red Hat Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# Lesser General Public License, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this distribution; if not, write to:
+# Free Software Foundation, Inc.
+# 51 Franklin Street, Fifth Floor
+# Boston, MA 02110-1301 USA
+#
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+
+log4j.rootLogger=info, stdout
Added: core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/pom.xml 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ ~ third-party contributors as indicated by either @author tags or express
+ ~ copyright attribution statements applied by the authors. All
+ ~ third-party contributions are distributed under license by Red Hat Inc.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-parent</artifactId>
+ <version>3.3.2.GA_CP01</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>hibernate-jdbc4-testing</artifactId>
+ <name>Hibernate JDBC4-JdbcSupport Testing</name>
+ <description>Test support of JDBC4 through JdbcSupport</description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <compilerVersion>1.6</compilerVersion>
+ <executable>${jdk16_home}/bin/javac</executable>
+ <fork>true</fork>
+ <verbose>true</verbose>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <jvm>${jdk16_home}/bin/java</jvm>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added: core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/java/org/hibernate/engine/jdbc/jdbc4/JdbcSupportTest.java 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,347 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc.jdbc4;
+
+import java.sql.*;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+import junit.framework.TestCase;
+
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.engine.jdbc.JdbcSupportLoader;
+import org.hibernate.engine.jdbc.ContextualLobCreator;
+import org.hibernate.engine.jdbc.BlobImplementer;
+import org.hibernate.engine.jdbc.ClobImplementer;
+import org.hibernate.engine.jdbc.NClobImplementer;
+import org.hibernate.engine.jdbc.NonContextualLobCreator;
+import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.engine.jdbc.WrappedClob;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcSupportTest extends TestCase {
+ public void testConnectedLobCreator() throws SQLException {
+ final Connection connection = createConnectionProxy(
+ 4,
+ new JdbcLobBuilder() {
+ public Blob createBlob() {
+ return new JdbcBlob();
+ }
+
+ public Clob createClob() {
+ return new JdbcClob();
+ }
+
+ public NClob createNClob() {
+ return new JdbcNClob();
+ }
+ }
+ );
+ final LobCreationContext lobCreationContext = new LobCreationContext() {
+ public Object execute(Callback callback) {
+ try {
+ return callback.executeOnConnection( connection );
+ }
+ catch ( SQLException e ) {
+ throw new RuntimeException( "Unexpected SQLException", e );
+ }
+ }
+ };
+
+ LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( connection ).getLobCreator( lobCreationContext );
+ assertTrue( lobCreator instanceof ContextualLobCreator );
+
+ Blob blob = lobCreator.createBlob( new byte[] {} );
+ assertTrue( blob instanceof JdbcBlob );
+ blob = lobCreator.wrap( blob );
+ assertTrue( blob instanceof WrappedBlob );
+
+ Clob clob = lobCreator.createClob( "Hi" );
+ assertTrue( clob instanceof JdbcClob );
+ clob = lobCreator.wrap( clob );
+ assertTrue( clob instanceof WrappedClob );
+
+ Clob nclob = lobCreator.createNClob( "Hi" );
+ assertTrue( nclob instanceof JdbcNClob );
+ nclob = lobCreator.wrap( nclob );
+ assertTrue( nclob instanceof WrappedClob );
+
+ blob.free();
+ clob.free();
+ nclob.free();
+ connection.close();
+ }
+
+ public void testConnectedLobCreatorWithUnSupportedCreations() throws SQLException {
+ final Connection connection = createConnectionProxy(
+ 3,
+ new JdbcLobBuilder() {
+ public Blob createBlob() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Clob createClob() {
+ throw new UnsupportedOperationException();
+ }
+
+ public NClob createNClob() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ );
+ final LobCreationContext lobCreationContext = new LobCreationContext() {
+ public Object execute(Callback callback) {
+ try {
+ return callback.executeOnConnection( connection );
+ }
+ catch ( SQLException e ) {
+ throw new RuntimeException( "Unexpected SQLException", e );
+ }
+ }
+ };
+
+ LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( connection ).getLobCreator( lobCreationContext );
+ assertTrue( lobCreator instanceof NonContextualLobCreator );
+
+ Blob blob = lobCreator.createBlob( new byte[] {} );
+ assertTrue( blob instanceof BlobImplementer );
+ blob = lobCreator.wrap( blob );
+ assertTrue( blob instanceof WrappedBlob );
+
+ Clob clob = lobCreator.createClob( "Hi" );
+ assertTrue( clob instanceof ClobImplementer );
+ clob = lobCreator.wrap( clob );
+ assertTrue( clob instanceof WrappedClob );
+
+ Clob nclob = lobCreator.createNClob( "Hi" );
+ assertTrue( nclob instanceof ClobImplementer );
+ assertTrue( nclob instanceof NClobImplementer );
+ nclob = lobCreator.wrap( nclob );
+ assertTrue( nclob instanceof WrappedClob );
+
+ blob.free();
+ clob.free();
+ nclob.free();
+ connection.close();
+ }
+
+ public void testLegacyLobCreator() throws SQLException {
+ LobCreator lobCreator = JdbcSupportLoader.loadJdbcSupport( null ).getLobCreator();
+
+ Blob blob = lobCreator.createBlob( new byte[] {} );
+ assertTrue( blob instanceof BlobImplementer );
+ blob = lobCreator.wrap( blob );
+ assertTrue( blob instanceof WrappedBlob );
+
+ Clob clob = lobCreator.createClob( "Hi" );
+ assertTrue( clob instanceof ClobImplementer );
+ clob = lobCreator.wrap( clob );
+ assertTrue( clob instanceof WrappedClob );
+
+ Clob nclob = lobCreator.createNClob( "Hi" );
+ assertTrue( nclob instanceof NClobImplementer );
+ assertTrue( NClob.class.isInstance( nclob ) );
+ nclob = lobCreator.wrap( nclob );
+ assertTrue( nclob instanceof WrappedClob );
+
+ blob.free();
+ clob.free();
+ nclob.free();
+ }
+
+ private interface JdbcLobBuilder {
+ public Blob createBlob();
+ public Clob createClob();
+ public NClob createNClob();
+ }
+
+ private class ConnectionProxyHandler implements InvocationHandler {
+ private final JdbcLobBuilder lobBuilder;
+ private final DatabaseMetaData metadata;
+
+ private ConnectionProxyHandler(int version, JdbcLobBuilder lobBuilder) {
+ this.lobBuilder = lobBuilder;
+ this.metadata = createMetadataProxy( version );
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ // the only methods we are interested in are the LOB creation methods...
+ if ( args == null || args.length == 0 ) {
+ final String methodName = method.getName();
+ if ( "createBlob".equals( methodName ) ) {
+ return lobBuilder.createBlob();
+ }
+ else if ( "createClob".equals( methodName ) ) {
+ return lobBuilder.createClob();
+ }
+ else if ( "createNClob".equals( methodName ) ) {
+ return lobBuilder.createNClob();
+ }
+ else if ( "getMetaData".equals( methodName ) ) {
+ return metadata;
+ }
+ }
+ return null;
+ }
+ }
+
+ private static Class[] CONN_PROXY_TYPES = new Class[] { Connection.class };
+
+ private Connection createConnectionProxy(int version, JdbcLobBuilder jdbcLobBuilder) {
+ ConnectionProxyHandler handler = new ConnectionProxyHandler( version, jdbcLobBuilder );
+ return ( Connection ) Proxy.newProxyInstance( getClass().getClassLoader(), CONN_PROXY_TYPES, handler );
+ }
+
+ private class MetadataProxyHandler implements InvocationHandler {
+ private final int jdbcVersion;
+
+ private MetadataProxyHandler(int jdbcVersion) {
+ this.jdbcVersion = jdbcVersion;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ( "getJDBCMajorVersion".equals( methodName ) ) {
+ return jdbcVersion;
+ }
+ return null;
+ }
+ }
+
+ private static Class[] META_PROXY_TYPES = new Class[] { DatabaseMetaData.class };
+
+ private DatabaseMetaData createMetadataProxy(int version) {
+ MetadataProxyHandler handler = new MetadataProxyHandler( version );
+ return ( DatabaseMetaData ) Proxy.newProxyInstance( getClass().getClassLoader(), META_PROXY_TYPES, handler );
+ }
+
+ private class JdbcBlob implements Blob {
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ public byte[] getBytes(long pos, int length) throws SQLException {
+ return new byte[0];
+ }
+
+ public InputStream getBinaryStream() throws SQLException {
+ return null;
+ }
+
+ public long position(byte[] pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ public long position(Blob pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ public int setBytes(long pos, byte[] bytes) throws SQLException {
+ return 0;
+ }
+
+ public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ public OutputStream setBinaryStream(long pos) throws SQLException {
+ return null;
+ }
+
+ public void truncate(long len) throws SQLException {
+ }
+
+ public void free() throws SQLException {
+ }
+
+ public InputStream getBinaryStream(long pos, long length) throws SQLException {
+ return null;
+ }
+ }
+
+ private class JdbcClob implements Clob {
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ public String getSubString(long pos, int length) throws SQLException {
+ return null;
+ }
+
+ public Reader getCharacterStream() throws SQLException {
+ return null;
+ }
+
+ public InputStream getAsciiStream() throws SQLException {
+ return null;
+ }
+
+ public long position(String searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ public long position(Clob searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ public int setString(long pos, String str) throws SQLException {
+ return 0;
+ }
+
+ public int setString(long pos, String str, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ public OutputStream setAsciiStream(long pos) throws SQLException {
+ return null;
+ }
+
+ public Writer setCharacterStream(long pos) throws SQLException {
+ return null;
+ }
+
+ public void truncate(long len) throws SQLException {
+ }
+
+ public void free() throws SQLException {
+ }
+
+ public Reader getCharacterStream(long pos, long length) throws SQLException {
+ return null;
+ }
+ }
+
+ private class JdbcNClob extends JdbcClob implements NClob {
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/jdbc4-testing/src/test/resources/log4j.properties 2010-04-27 07:17:09 UTC (rev 19300)
@@ -0,0 +1,7 @@
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+
+log4j.rootLogger=info, stdout
14 years, 7 months
Hibernate SVN: r19299 - annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-27 03:07:12 -0400 (Tue, 27 Apr 2010)
New Revision: 19299
Modified:
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/SerializableToBlobType.java
Log:
JBPAPP-4180 HHH-2412 Support for JDBC4
Modified: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java 2010-04-27 06:22:15 UTC (rev 19298)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java 2010-04-27 07:07:12 UTC (rev 19299)
@@ -12,11 +12,10 @@
import org.dom4j.Node;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
import org.hibernate.util.ArrayHelper;
/**
@@ -27,9 +26,9 @@
*/
@Deprecated
public class ByteArrayBlobType extends AbstractLobType {
-
- public int[] sqlTypes(Mapping mapping) throws MappingException {
- return new int[]{Types.BLOB};
+ private static final int[] TYPES = new int[] { Types.BLOB };
+ public int[] sqlTypes(Mapping mapping) {
+ return TYPES;
}
@Override
@@ -104,7 +103,7 @@
st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
}
else {
- st.setBlob( index, new BlobImpl( toSet ) );
+ st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
}
}
}
Modified: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/SerializableToBlobType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/SerializableToBlobType.java 2010-04-27 06:22:15 UTC (rev 19298)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/SerializableToBlobType.java 2010-04-27 07:07:12 UTC (rev 19299)
@@ -15,10 +15,10 @@
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.SerializationHelper;
@@ -77,7 +77,7 @@
st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
}
else {
- st.setBlob( index, new BlobImpl( toSet ) );
+ st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
}
}
else {
14 years, 7 months
Hibernate SVN: r19298 - in annotations/branches/v3_4_0_GA_CP/src: main/java/org/hibernate/type and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-27 02:22:15 -0400 (Tue, 27 Apr 2010)
New Revision: 19298
Added:
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/CharacterArrayTextType.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/Dog.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageHolder.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LongStringHolder.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/PrimitiveCharacterArrayTextType.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/TextTest.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/WrappedImageType.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/package-info.java
Modified:
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java
annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/StringClobType.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/TestCase.java
annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LobTest.java
Log:
JBPAPP-2861 HHH-4405 Integrate new long string and binary property types in core with annotations
Modified: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java 2010-04-27 05:46:04 UTC (rev 19297)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -13,6 +13,7 @@
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
+import org.hibernate.Hibernate;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.common.reflection.XClass;
@@ -23,13 +24,11 @@
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
-import org.hibernate.type.ByteArrayBlobType;
import org.hibernate.type.CharacterArrayClobType;
import org.hibernate.type.EnumType;
-import org.hibernate.type.PrimitiveByteArrayBlobType;
import org.hibernate.type.PrimitiveCharacterArrayClobType;
import org.hibernate.type.SerializableToBlobType;
-import org.hibernate.type.StringClobType;
+import org.hibernate.type.WrappedMaterializedBlobType;
import org.hibernate.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -126,7 +125,7 @@
type = "blob";
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, String.class ) ) {
- type = StringClobType.class.getName();
+ type = Hibernate.MATERIALIZED_CLOB.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Character.class ) && isArray ) {
type = CharacterArrayClobType.class.getName();
@@ -135,10 +134,10 @@
type = PrimitiveCharacterArrayClobType.class.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Byte.class ) && isArray ) {
- type = ByteArrayBlobType.class.getName();
+ type = WrappedMaterializedBlobType.class.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, byte.class ) && isArray ) {
- type = PrimitiveByteArrayBlobType.class.getName();
+ type = Hibernate.MATERIALIZED_BLOB.getName();
}
else if ( mappings.getReflectionManager()
.toXClass( Serializable.class )
Modified: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java 2010-04-27 05:46:04 UTC (rev 19297)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/ByteArrayBlobType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -22,9 +22,10 @@
/**
* Map a Byte[] into a Blob
* Experimental
- *
+ * @deprecated replaced by Hibernate Core's {@link org.hibernate.type.WrappedMaterializedBlobType}
* @author Emmanuel Bernard
*/
+@Deprecated
public class ByteArrayBlobType extends AbstractLobType {
public int[] sqlTypes(Mapping mapping) throws MappingException {
Modified: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java 2010-04-27 05:46:04 UTC (rev 19297)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -3,9 +3,10 @@
/**
* Map a byte[] to a Blob
- *
+ * @deprecated replaced by Hibernate Core's {@link org.hibernate.type.MaterializedBlobType}
* @author Emmanuel Bernard
*/
+@Deprecated
public class PrimitiveByteArrayBlobType extends ByteArrayBlobType {
public Class getReturnedClass() {
return byte[].class;
Modified: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/StringClobType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/StringClobType.java 2010-04-27 05:46:04 UTC (rev 19297)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/StringClobType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -15,9 +15,10 @@
/**
* Map a String to a Clob
- *
+ * @deprecated replaced by Hibernate Core's {@link org.hibernate.type.MaterializedClobType}
* @author Emmanuel Bernard
*/
+@Deprecated
public class StringClobType implements UserType, Serializable {
public int[] sqlTypes() {
return new int[]{Types.CLOB};
Added: annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,42 @@
+package org.hibernate.type;
+
+/**
+ * <tt>materialized_blob</tt>: A type that maps an SQL BLOB to Java Byte[].
+ *
+ * @author Strong Liu
+ */
+public class WrappedMaterializedBlobType extends MaterializedBlobType {
+ public Class getReturnedClass() {
+ return Byte[].class;
+ }
+
+ protected Object toExternalFormat(byte[] bytes) {
+ if (bytes == null)
+ return null;
+ return wrapPrimitive(bytes);
+ }
+
+ protected byte[] toInternalFormat(Object bytes) {
+ if (bytes == null)
+ return null;
+ return unwrapNonPrimitive((Byte[]) bytes);
+ }
+
+ private Byte[] wrapPrimitive(byte[] bytes) {
+ int length = bytes.length;
+ Byte[] result = new Byte[length];
+ for (int index = 0; index < length; index++) {
+ result[index] = Byte.valueOf(bytes[index]);
+ }
+ return result;
+ }
+
+ private byte[] unwrapNonPrimitive(Byte[] bytes) {
+ int length = bytes.length;
+ byte[] result = new byte[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = bytes[i].byteValue();
+ }
+ return result;
+ }
+}
Modified: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/TestCase.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/TestCase.java 2010-04-27 05:46:04 UTC (rev 19297)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/TestCase.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -156,14 +156,16 @@
else {
// check whether the current dialect is assignableFrom from any of the specified required dialects.
for ( Class<? extends Dialect> dialect : requiredDialectList ) {
- if ( dialect.isAssignableFrom( Dialect.getDialect().getClass() ) ) {
+ if ( ( dialect.isAssignableFrom( Dialect.getDialect().getClass() ) ) && appliesTo( Dialect.getDialect() ) ){
return true;
}
}
return false;
}
}
-
+ protected boolean appliesTo( Dialect dialect ){
+ return true;
+ }
private void runTestMethod(Method runMethod) throws Throwable {
try {
runMethod.invoke( this, new Class[0] );
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/CharacterArrayTextType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/CharacterArrayTextType.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/CharacterArrayTextType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,79 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * A type that maps an SQL LONGVARCHAR to a Java Character [].
+ *
+ * @author Strong Liu
+ */
+public class CharacterArrayTextType extends PrimitiveCharacterArrayTextType {
+
+ public Class getReturnedClass() {
+ return Character[].class;
+ }
+
+ @Override
+ public Object get(ResultSet rs, String name) throws HibernateException,
+ SQLException {
+ char[] text = (char[]) super.get(rs, name);
+ if (text == null)
+ return null;
+ return wrapPrimitive(text);
+ }
+
+ @Override
+ public void set(PreparedStatement st, Object value, int index)
+ throws HibernateException, SQLException {
+ Character[] cs = (Character[]) value;
+ super.set(st, unwrapNonPrimitive(cs), index);
+ }
+
+ private Character[] wrapPrimitive(char[] bytes) {
+ int length = bytes.length;
+ Character[] result = new Character[length];
+ for (int index = 0; index < length; index++) {
+ result[index] = Character.valueOf(bytes[index]);
+ }
+ return result;
+ }
+
+ private char[] unwrapNonPrimitive(Character[] bytes) {
+ int length = bytes.length;
+ char[] result = new char[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = bytes[i].charValue();
+ }
+ return result;
+ }
+
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/Dog.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/Dog.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/Dog.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,15 @@
+package org.hibernate.test.annotations.lob;
+
+import java.io.Serializable;
+
+public class Dog implements Serializable {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageHolder.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageHolder.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageHolder.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,81 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * An entity containing data that is materialized into a byte array immediately.
+ * The hibernate type mapped for {@link #longByteArray} determines the SQL type
+ * asctually used.
+ *
+ * @author Gail Badner
+ */
+@Entity
+public class ImageHolder {
+ private Long id;
+ private byte[] longByteArray;
+ private Dog dog;
+ private Byte[] picByteArray;
+
+ @Id
+ @GeneratedValue
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ @org.hibernate.annotations.Type(type="image")
+ public byte[] getLongByteArray() {
+ return longByteArray;
+ }
+
+ public void setLongByteArray(byte[] longByteArray) {
+ this.longByteArray = longByteArray;
+ }
+ @org.hibernate.annotations.Type(type="serializable_image")
+ public Dog getDog() {
+ return dog;
+ }
+
+ public void setDog(Dog dog) {
+ this.dog = dog;
+ }
+ @org.hibernate.annotations.Type(type="wrapped_image")
+ public Byte[] getPicByteArray() {
+ return picByteArray;
+ }
+
+ public void setPicByteArray(Byte[] picByteArray) {
+ this.picByteArray = picByteArray;
+ }
+
+}
\ No newline at end of file
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,168 @@
+//$Id: ImageTest.java 18638 2010-01-26 20:11:51Z steve.ebersole(a)jboss.com $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import junit.framework.AssertionFailedError;
+
+import org.hibernate.Session;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.test.annotations.RequiresDialect;
+import org.hibernate.test.annotations.TestCase;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.ImageType}.
+ *
+ * @author Gail Badner
+ */
+@RequiresDialect( { SybaseASE15Dialect.class, SQLServerDialect.class,
+ SybaseDialect.class, Sybase11Dialect.class })
+public class ImageTest extends TestCase {
+ private static final int ARRAY_SIZE = 10000;
+
+ public void testBoundedLongByteArrayAccess() {
+ byte[] original = buildRecursively(ARRAY_SIZE, true);
+ byte[] changed = buildRecursively(ARRAY_SIZE, false);
+
+ Session s = openSession();
+ s.beginTransaction();
+ ImageHolder entity = new ImageHolder();
+ s.save(entity);
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (ImageHolder) s.get(ImageHolder.class, entity.getId());
+ assertNull(entity.getLongByteArray());
+ assertNull(entity.getDog());
+ assertNull(entity.getPicByteArray());
+ entity.setLongByteArray(original);
+ Dog dog = new Dog();
+ dog.setName("rabbit");
+ entity.setDog(dog);
+ entity.setPicByteArray(wrapPrimitive(original));
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (ImageHolder) s.get(ImageHolder.class, entity.getId());
+ assertEquals(ARRAY_SIZE, entity.getLongByteArray().length);
+ assertEquals(original, entity.getLongByteArray());
+ assertEquals(ARRAY_SIZE, entity.getPicByteArray().length);
+ assertEquals(original, unwrapNonPrimitive(entity.getPicByteArray()));
+ assertNotNull(entity.getDog());
+ assertEquals(dog.getName(), entity.getDog().getName());
+ entity.setLongByteArray(changed);
+ entity.setPicByteArray(wrapPrimitive(changed));
+ dog.setName("papa");
+ entity.setDog(dog);
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (ImageHolder) s.get(ImageHolder.class, entity.getId());
+ assertEquals(ARRAY_SIZE, entity.getLongByteArray().length);
+ assertEquals(changed, entity.getLongByteArray());
+ assertEquals(ARRAY_SIZE, entity.getPicByteArray().length);
+ assertEquals(changed, unwrapNonPrimitive(entity.getPicByteArray()));
+ assertNotNull(entity.getDog());
+ assertEquals(dog.getName(), entity.getDog().getName());
+ entity.setLongByteArray(null);
+ entity.setPicByteArray(null);
+ entity.setDog(null);
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (ImageHolder) s.get(ImageHolder.class, entity.getId());
+ assertNull(entity.getLongByteArray());
+ assertNull(entity.getDog());
+ assertNull(entity.getPicByteArray());
+ s.delete(entity);
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private Byte[] wrapPrimitive(byte[] bytes) {
+ int length = bytes.length;
+ Byte[] result = new Byte[length];
+ for (int index = 0; index < length; index++) {
+ result[index] = Byte.valueOf(bytes[index]);
+ }
+ return result;
+ }
+
+ private byte[] unwrapNonPrimitive(Byte[] bytes) {
+ int length = bytes.length;
+ byte[] result = new byte[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = bytes[i].byteValue();
+ }
+ return result;
+ }
+
+ private byte[] buildRecursively(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask(on);
+ for (int i = 0; i < size; i++) {
+ data[i] = mask(on);
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? (byte) 1 : (byte) 0;
+ }
+
+ public static void assertEquals(byte[] val1, byte[] val2) {
+ if (!ArrayHelper.isEquals(val1, val2)) {
+ throw new AssertionFailedError("byte arrays did not match");
+ }
+ }
+
+ public ImageTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected String[] getAnnotatedPackages() {
+ return new String[] { "org.hibernate.test.annotations.lob" };
+ }
+
+ public Class<?>[] getMappings() {
+ return new Class[] { ImageHolder.class };
+ }
+
+}
\ No newline at end of file
Modified: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LobTest.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LobTest.java 2010-04-27 05:46:04 UTC (rev 19297)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LobTest.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -122,7 +122,7 @@
public LobTest(String x) {
super( x );
}
-
+
protected Class[] getMappings() {
return new Class[]{
Book.class,
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LongStringHolder.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LongStringHolder.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/LongStringHolder.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,82 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.annotations.Type;
+
+/**
+ * An entity containing data that is materialized into a String immediately.
+ * The hibernate type mapped for {@link #LONGVARCHAR} determines the SQL type
+ * asctually used.
+ *
+ * @author Gail Badner
+ */
+@Entity
+public class LongStringHolder {
+ private Long id;
+ private char[] name;
+ private Character[] whatEver;
+ private String longString;
+
+ @Id
+ @GeneratedValue
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ @Type(type = "text")
+ public String getLongString() {
+ return longString;
+ }
+
+ public void setLongString(String longString) {
+ this.longString = longString;
+ }
+ @Type(type = "char_text")
+ public char[] getName() {
+ return name;
+ }
+
+ public void setName(char[] name) {
+ this.name = name;
+ }
+ @Type(type = "wrapped_char_text")
+ public Character[] getWhatEver() {
+ return whatEver;
+ }
+
+ public void setWhatEver(Character[] whatEver) {
+ this.whatEver = whatEver;
+ }
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/PrimitiveCharacterArrayTextType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/PrimitiveCharacterArrayTextType.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/PrimitiveCharacterArrayTextType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,68 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.type.TextType;
+
+/**
+ * A type that maps an SQL LONGVARCHAR to a Java char [].
+ *
+ * @author Strong Liu
+ */
+public class PrimitiveCharacterArrayTextType extends TextType {
+ public Class getReturnedClass() {
+ return char[].class;
+ }
+
+ @Override
+ public Object get(ResultSet rs, String name) throws HibernateException,
+ SQLException {
+ String text = (String) super.get(rs, name);
+ if (text == null)
+ return null;
+ return text.toCharArray();
+ }
+
+ @Override
+ public void set(PreparedStatement st, Object value, int index)
+ throws HibernateException, SQLException {
+ char[] cs = (char[]) value;
+ String text = String.valueOf(cs);
+
+ super.set(st, text, index);
+ }
+
+ @Override
+ public String toString(Object val) {
+ return String.valueOf(val);
+ }
+
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,52 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import java.io.Serializable;
+
+import org.hibernate.type.ImageType;
+import org.hibernate.util.SerializationHelper;
+
+/**
+ * A type that maps an SQL LONGVARBINARY to a serializable Java object.
+ *
+ * @author Strong Liu
+ */
+public class SerializableToImageType extends ImageType {
+ public Class getReturnedClass() {
+ return Serializable.class;
+ }
+
+ protected Object toExternalFormat(byte[] bytes) {
+ if (bytes == null)
+ return null;
+ return SerializationHelper.deserialize( bytes, getReturnedClass().getClassLoader() );
+ }
+
+ protected byte[] toInternalFormat(Object bytes) {
+ return SerializationHelper.serialize((Serializable) bytes);
+ }
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/TextTest.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/TextTest.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/TextTest.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,163 @@
+//$Id: TextTest.java 18638 2010-01-26 20:11:51Z steve.ebersole(a)jboss.com $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import junit.framework.AssertionFailedError;
+
+import org.hibernate.Session;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.test.annotations.RequiresDialect;
+import org.hibernate.test.annotations.TestCase;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Tests eager materialization and mutation of long strings.
+ *
+ * @author Steve Ebersole
+ */
+(a)RequiresDialect({SybaseASE15Dialect.class,SQLServerDialect.class,SybaseDialect.class,Sybase11Dialect.class})
+public class TextTest extends TestCase {
+
+ @Override
+ protected Class<?>[] getMappings() {
+ return new Class[] { LongStringHolder.class };
+ }
+
+ private static final int LONG_STRING_SIZE = 10000;
+
+ public void testBoundedLongStringAccess() {
+ String original = buildRecursively(LONG_STRING_SIZE, 'x');
+ String changed = buildRecursively(LONG_STRING_SIZE, 'y');
+
+ Session s = openSession();
+ s.beginTransaction();
+ LongStringHolder entity = new LongStringHolder();
+ s.save(entity);
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (LongStringHolder) s.get(LongStringHolder.class, entity
+ .getId());
+ assertNull(entity.getLongString());
+ assertNull(entity.getName());
+ assertNull(entity.getWhatEver());
+ entity.setLongString(original);
+ entity.setName(original.toCharArray());
+ entity.setWhatEver(wrapPrimitive(original.toCharArray()));
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (LongStringHolder) s.get(LongStringHolder.class, entity
+ .getId());
+ assertEquals(LONG_STRING_SIZE, entity.getLongString().length());
+ assertEquals(original, entity.getLongString());
+ assertNotNull(entity.getName());
+ assertEquals(LONG_STRING_SIZE, entity.getName().length);
+ assertEquals(original.toCharArray(), entity.getName());
+ assertNotNull(entity.getWhatEver());
+ assertEquals(LONG_STRING_SIZE, entity.getWhatEver().length);
+ assertEquals(original.toCharArray(), unwrapNonPrimitive(entity.getWhatEver()));
+ entity.setLongString(changed);
+ entity.setName(changed.toCharArray());
+ entity.setWhatEver(wrapPrimitive(changed.toCharArray()));
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (LongStringHolder) s.get(LongStringHolder.class, entity
+ .getId());
+ assertEquals(LONG_STRING_SIZE, entity.getLongString().length());
+ assertEquals(changed, entity.getLongString());
+ assertNotNull(entity.getName());
+ assertEquals(LONG_STRING_SIZE, entity.getName().length);
+ assertEquals(changed.toCharArray(), entity.getName());
+ assertNotNull(entity.getWhatEver());
+ assertEquals(LONG_STRING_SIZE, entity.getWhatEver().length);
+ assertEquals(changed.toCharArray(), unwrapNonPrimitive(entity.getWhatEver()));
+ entity.setLongString(null);
+ entity.setName(null);
+ entity.setWhatEver(null);
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = (LongStringHolder) s.get(LongStringHolder.class, entity
+ .getId());
+ assertNull(entity.getLongString());
+ assertNull(entity.getName());
+ assertNull(entity.getWhatEver());
+ s.delete(entity);
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public static void assertEquals(char[] val1, char[] val2) {
+ if (!ArrayHelper.isEquals(val1, val2)) {
+ throw new AssertionFailedError("byte arrays did not match");
+ }
+ }
+
+ private String buildRecursively(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for (int i = 0; i < size; i++) {
+ buff.append(baseChar);
+ }
+ return buff.toString();
+ }
+
+ private Character[] wrapPrimitive(char[] bytes) {
+ int length = bytes.length;
+ Character[] result = new Character[length];
+ for (int index = 0; index < length; index++) {
+ result[index] = Character.valueOf(bytes[index]);
+ }
+ return result;
+ }
+
+ private char[] unwrapNonPrimitive(Character[] bytes) {
+ int length = bytes.length;
+ char[] result = new char[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = bytes[i].charValue();
+ }
+ return result;
+ }
+
+ @Override
+ protected String[] getAnnotatedPackages() {
+ return new String[] { "org.hibernate.test.annotations.lob" };
+ }
+
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/WrappedImageType.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/WrappedImageType.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/WrappedImageType.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,66 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.annotations.lob;
+
+import org.hibernate.type.ImageType;
+
+/**
+ * A type that maps an SQL LONGVARBINARY to Java Byte[].
+ *
+ * @author Strong Liu
+ */
+public class WrappedImageType extends ImageType{
+ public Class getReturnedClass() {
+ return Byte[].class;
+ }
+
+ protected Object toExternalFormat(byte[] bytes) {
+ if(bytes==null)return null;
+ return wrapPrimitive(bytes);
+ }
+
+ protected byte[] toInternalFormat(Object bytes) {
+ if(bytes==null)return null;
+ return unwrapNonPrimitive(( Byte[] ) bytes);
+ }
+ private Byte[] wrapPrimitive(byte[] bytes) {
+ int length = bytes.length;
+ Byte[] result = new Byte[length];
+ for ( int index = 0; index < length ; index++ ) {
+ result[index] = Byte.valueOf( bytes[index] );
+ }
+ return result;
+ }
+
+ private byte[] unwrapNonPrimitive(Byte[] bytes) {
+ int length = bytes.length;
+ byte[] result = new byte[length];
+ for ( int i = 0; i < length ; i++ ) {
+ result[i] = bytes[i].byteValue();
+ }
+ return result;
+ }
+}
Added: annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/package-info.java
===================================================================
--- annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/package-info.java (rev 0)
+++ annotations/branches/v3_4_0_GA_CP/src/test/java/org/hibernate/test/annotations/lob/package-info.java 2010-04-27 06:22:15 UTC (rev 19298)
@@ -0,0 +1,29 @@
+/**
+ * Test package for metatata facilities
+ * It contains an example of filter metadata
+ */
+@TypeDefs(
+ {
+ @TypeDef(
+ name = "wrapped_char_text",
+ typeClass = org.hibernate.test.annotations.lob.CharacterArrayTextType.class
+ ),
+ @TypeDef(
+ name = "char_text",
+ typeClass = org.hibernate.test.annotations.lob.PrimitiveCharacterArrayTextType.class
+ ),
+ @TypeDef(
+ name = "wrapped_image",
+ typeClass = org.hibernate.test.annotations.lob.WrappedImageType.class
+ ),
+ @TypeDef(
+ name = "serializable_image",
+ typeClass = org.hibernate.test.annotations.lob.SerializableToImageType.class
+ )
+ }
+)
+package org.hibernate.test.annotations.lob;
+
+import org.hibernate.annotations.TypeDef;
+import org.hibernate.annotations.TypeDefs;
+
14 years, 7 months
Hibernate SVN: r19297 - in core/branches/Branch_3_3_2_GA_CP: core/src/main/java/org/hibernate/dialect and 10 other directories.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-27 01:46:04 -0400 (Tue, 27 Apr 2010)
New Revision: 19297
Added:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongStringType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ImageType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedBlobType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedClobType.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/ImageHolder.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/TextHolder.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/Mappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/SQLServerCustomSQLTest.java
Removed:
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Dialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TextType.java
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TypeFactory.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/db2/Mappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/mysql/Mappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/oracle/Mappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/Mappings.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/SybaseCustomSQLTest.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java
Log:
JBPAPP-2860 HHH-3892 - Improve support for mapping SQL LONGVARCHAR and CLOB to Java String, SQL LONGVARBINARY and BLOB to Java byte[]
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/Hibernate.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -61,10 +61,13 @@
import org.hibernate.type.DateType;
import org.hibernate.type.DoubleType;
import org.hibernate.type.FloatType;
+import org.hibernate.type.ImageType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LocaleType;
import org.hibernate.type.LongType;
import org.hibernate.type.ManyToOneType;
+import org.hibernate.type.MaterializedBlobType;
+import org.hibernate.type.MaterializedClobType;
import org.hibernate.type.NullableType;
import org.hibernate.type.SerializableType;
import org.hibernate.type.ShortType;
@@ -178,10 +181,23 @@
*/
public static final NullableType CHARACTER_ARRAY = new CharacterArrayType();
/**
+ * Hibernate <tt>image</tt> type.
+ */
+ public static final NullableType IMAGE = new ImageType();
+ /**
* Hibernate <tt>text</tt> type.
*/
public static final NullableType TEXT = new TextType();
/**
+ * Hibernate <tt>materialized_blob</tt> type.
+ */
+ public static final NullableType MATERIALIZED_BLOB = new MaterializedBlobType();
+ /**
+ * Hibernate <tt>materialized_clob</tt> type.
+ */
+ public static final NullableType MATERIALIZED_CLOB = new MaterializedClobType();
+
+ /**
* Hibernate <tt>blob</tt> type.
*/
public static final Type BLOB = new BlobType();
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -61,6 +61,8 @@
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
registerColumnType( Types.BLOB, "blob($l)" );
registerColumnType( Types.CLOB, "clob($l)" );
+ registerColumnType( Types.LONGVARCHAR, "long varchar" );
+ registerColumnType( Types.LONGVARBINARY, "long varchar for bit data" );
registerFunction("abs", new StandardSQLFunction("abs") );
registerFunction("absval", new StandardSQLFunction("absval") );
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Dialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Dialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Dialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -216,6 +216,8 @@
registerHibernateType( Types.TIMESTAMP, Hibernate.TIMESTAMP.getName() );
registerHibernateType( Types.VARCHAR, Hibernate.STRING.getName() );
registerHibernateType( Types.VARBINARY, Hibernate.BINARY.getName() );
+ registerHibernateType( Types.LONGVARCHAR, Hibernate.TEXT.getName() );
+ registerHibernateType( Types.LONGVARBINARY, Hibernate.IMAGE.getName() );
registerHibernateType( Types.NUMERIC, Hibernate.BIG_DECIMAL.getName() );
registerHibernateType( Types.DECIMAL, Hibernate.BIG_DECIMAL.getName() );
registerHibernateType( Types.BLOB, Hibernate.BLOB.getName() );
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -81,6 +81,8 @@
//HSQL has no Blob/Clob support .... but just put these here for now!
registerColumnType( Types.BLOB, "longvarbinary" );
registerColumnType( Types.CLOB, "longvarchar" );
+ registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
+ registerColumnType( Types.LONGVARCHAR, "longvarchar" );
registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.INTEGER ) );
registerFunction( "char", new StandardSQLFunction( "char", Hibernate.CHARACTER ) );
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -36,5 +36,6 @@
registerColumnType( Types.VARCHAR, "longtext" );
// registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
registerColumnType( Types.VARCHAR, 65535, "varchar($l)" );
+ registerColumnType( Types.LONGVARCHAR, "longtext" );
}
}
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -59,6 +59,8 @@
registerColumnType( Types.VARBINARY, 16777215, "mediumblob" );
registerColumnType( Types.VARBINARY, 65535, "blob" );
registerColumnType( Types.VARBINARY, 255, "tinyblob" );
+ registerColumnType( Types.LONGVARBINARY, "longblob" );
+ registerColumnType( Types.LONGVARBINARY, 16777215, "mediumblob" );
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
registerColumnType( Types.BLOB, "longblob" );
// registerColumnType( Types.BLOB, 16777215, "mediumblob" );
@@ -181,6 +183,8 @@
// registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
// registerColumnType( Types.VARCHAR, 65535, "text" );
registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
+ registerColumnType( Types.LONGVARCHAR, "longtext" );
+
}
public String getAddColumnString() {
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -98,6 +98,9 @@
registerColumnType( Types.BLOB, "blob" );
registerColumnType( Types.CLOB, "clob" );
+
+ registerColumnType( Types.LONGVARCHAR, "long" );
+ registerColumnType( Types.LONGVARBINARY, "long raw" );
}
protected void registerReverseHibernateTypeMappings() {
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -62,6 +62,8 @@
registerColumnType( Types.TIME, "time" );
registerColumnType( Types.TIMESTAMP, "timestamp" );
registerColumnType( Types.VARBINARY, "bytea" );
+ registerColumnType( Types.LONGVARCHAR, "text" );
+ registerColumnType( Types.LONGVARBINARY, "bytea" );
registerColumnType( Types.CLOB, "text" );
registerColumnType( Types.BLOB, "oid" );
registerColumnType( Types.NUMERIC, "numeric($p, $s)" );
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -42,7 +42,8 @@
public SQLServerDialect() {
registerColumnType( Types.VARBINARY, "image" );
registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
-
+ registerColumnType( Types.LONGVARBINARY, "image" );
+ registerColumnType( Types.LONGVARCHAR, "text" );
registerFunction( "second", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(second, ?1)" ) );
registerFunction( "minute", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(minute, ?1)" ) );
registerFunction( "hour", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(hour, ?1)" ) );
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -25,6 +25,8 @@
*/
package org.hibernate.dialect;
+import java.sql.Types;
+
import org.hibernate.Hibernate;
import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
@@ -37,6 +39,8 @@
public class SybaseASE15Dialect extends AbstractTransactSQLDialect {
public SybaseASE15Dialect() {
super();
+ registerColumnType( Types.LONGVARBINARY, "image" );
+ registerColumnType( Types.LONGVARCHAR, "text" );
registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,46 @@
+//$Id: $
+/*
+ * 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.type;
+
+/**
+ * An abstract type for mapping long binary SQL types to Java byte[].
+ *
+ * @author Gail Badner
+ */
+public abstract class AbstractLongBinaryType extends AbstractBynaryType {
+
+ public Class getReturnedClass() {
+ return byte[].class;
+ }
+
+ protected Object toExternalFormat(byte[] bytes) {
+ return bytes;
+ }
+
+ protected byte[] toInternalFormat(Object bytes) {
+ return ( byte[] ) bytes;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongStringType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongStringType.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/AbstractLongStringType.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,94 @@
+//$Id: $
+/*
+ * 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.type;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * An abstract type for mapping long string SQL types to a Java String.
+ * @author Gavin King, Bertrand Renuart (from TextType)
+ */
+public abstract class AbstractLongStringType extends ImmutableType {
+
+ public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ String str = (String) value;
+ st.setCharacterStream( index, new StringReader(str), str.length() );
+ }
+
+ public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+
+ // Retrieve the value of the designated column in the current row of this
+ // ResultSet object as a java.io.Reader object
+ Reader charReader = rs.getCharacterStream(name);
+
+ // if the corresponding SQL value is NULL, the reader we got is NULL as well
+ if (charReader==null) return null;
+
+ // Fetch Reader content up to the end - and put characters in a StringBuffer
+ StringBuffer sb = new StringBuffer();
+ try {
+ char[] buffer = new char[2048];
+ while (true) {
+ int amountRead = charReader.read(buffer, 0, buffer.length);
+ if ( amountRead == -1 ) break;
+ sb.append(buffer, 0, amountRead);
+ }
+ }
+ catch (IOException ioe) {
+ throw new HibernateException( "IOException occurred reading text", ioe );
+ }
+ finally {
+ try {
+ charReader.close();
+ }
+ catch (IOException e) {
+ throw new HibernateException( "IOException occurred closing stream", e );
+ }
+ }
+
+ // Return StringBuffer content as a large String
+ return sb.toString();
+ }
+
+ public Class getReturnedClass() {
+ return String.class;
+ }
+
+ public String toString(Object val) {
+ return (String) val;
+ }
+ public Object fromStringValue(String xml) {
+ return xml;
+ }
+
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ImageType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ImageType.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/ImageType.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,44 @@
+//$Id: $
+/*
+ * 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.type;
+
+import java.sql.Types;
+
+/**
+ * <tt>image</tt>: A type that maps an SQL LONGVARBINARY to Java byte[].
+ *
+ * @author Gail Badner
+ */
+public class ImageType extends AbstractLongBinaryType {
+
+ public int sqlType() {
+ return Types.LONGVARBINARY;
+ }
+
+ public String getName() {
+ return "image";
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedBlobType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedBlobType.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedBlobType.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,44 @@
+//$Id: $
+/*
+ * 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.type;
+
+import java.sql.Types;
+
+/**
+ * <tt>materialized_blob</tt>: A type that maps an SQL BLOB to Java byte[].
+ *
+ * @author Gail Badner
+ */
+public class MaterializedBlobType extends AbstractLongBinaryType {
+
+ public int sqlType() {
+ return Types.BLOB;
+ }
+
+ public String getName() {
+ return "materialized_blob";
+ }
+}
Added: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedClobType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedClobType.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/MaterializedClobType.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,42 @@
+//$Id: $
+/*
+ * 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.type;
+
+import java.sql.Types;
+
+/**
+ * <tt>materialized_clob</tt>: A type that maps an SQL CLOB to a Java String.
+ *
+ * @author Gail Badner
+ */
+public class MaterializedClobType extends AbstractLongStringType {
+
+ public int sqlType() {
+ return Types.CLOB;
+ }
+
+ public String getName() { return "materialized_clob"; }
+}
\ No newline at end of file
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TextType.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TextType.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TextType.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -1,3 +1,4 @@
+//$Id: $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@@ -24,79 +25,21 @@
*/
package org.hibernate.type;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.sql.Types;
-import org.hibernate.HibernateException;
-
/**
- * <tt>text</tt>: A type that maps an SQL CLOB to a Java String.
+ * <tt>text</tt>: A type that maps an SQL LONGVARCHAR to a Java String.
+ *
* @author Gavin King, Bertrand Renuart
*/
-public class TextType extends ImmutableType {
+public class TextType extends AbstractLongStringType {
- public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
- String str = (String) value;
- st.setCharacterStream( index, new StringReader(str), str.length() );
- }
-
- public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-
- // Retrieve the value of the designated column in the current row of this
- // ResultSet object as a java.io.Reader object
- Reader charReader = rs.getCharacterStream(name);
-
- // if the corresponding SQL value is NULL, the reader we got is NULL as well
- if (charReader==null) return null;
-
- // Fetch Reader content up to the end - and put characters in a StringBuffer
- StringBuffer sb = new StringBuffer();
- try {
- char[] buffer = new char[2048];
- while (true) {
- int amountRead = charReader.read(buffer, 0, buffer.length);
- if ( amountRead == -1 ) break;
- sb.append(buffer, 0, amountRead);
- }
- }
- catch (IOException ioe) {
- throw new HibernateException( "IOException occurred reading text", ioe );
- }
- finally {
- try {
- charReader.close();
- }
- catch (IOException e) {
- throw new HibernateException( "IOException occurred closing stream", e );
- }
- }
-
- // Return StringBuffer content as a large String
- return sb.toString();
- }
-
public int sqlType() {
- return Types.CLOB; //or Types.LONGVARCHAR?
+ return Types.LONGVARCHAR;
}
- public Class getReturnedClass() {
- return String.class;
- }
-
public String getName() { return "text"; }
- public String toString(Object val) {
- return (String) val;
- }
- public Object fromStringValue(String xml) {
- return xml;
- }
-
}
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TypeFactory.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TypeFactory.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/type/TypeFactory.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -90,7 +90,10 @@
basics.put( Hibernate.TRUE_FALSE.getName(), Hibernate.TRUE_FALSE );
basics.put( Hibernate.YES_NO.getName(), Hibernate.YES_NO );
basics.put( Hibernate.BINARY.getName(), Hibernate.BINARY );
+ basics.put( Hibernate.IMAGE.getName(), Hibernate.IMAGE );
basics.put( Hibernate.TEXT.getName(), Hibernate.TEXT );
+ basics.put( Hibernate.MATERIALIZED_BLOB.getName(), Hibernate.MATERIALIZED_BLOB );
+ basics.put( Hibernate.MATERIALIZED_CLOB.getName(), Hibernate.MATERIALIZED_CLOB );
basics.put( Hibernate.BLOB.getName(), Hibernate.BLOB );
basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB );
basics.put( Hibernate.BIG_DECIMAL.getName(), Hibernate.BIG_DECIMAL );
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,196 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import java.sql.Blob;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Tests lazy materialization of data mapped by
+ * {@link org.hibernate.type.BlobType}, as well as bounded and unbounded
+ * materialization and mutation.
+ *
+ * @author Steve Ebersole
+ */
+public class BlobLocatorTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int BLOB_SIZE = 10000;
+
+ public BlobLocatorTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/LobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( BlobLocatorTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+
+ public void testBoundedBlobLocatorAccess() throws Throwable {
+ byte[] original = buildRecursively( BLOB_SIZE, true );
+ byte[] changed = buildRecursively( BLOB_SIZE, false );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setBlobLocator( Hibernate.createBlob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( original, extractData( entity.getBlobLocator() ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // test mutation via setting the new clob data...
+ if ( supportsLobValueChangePropogation() ) {
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ entity.getBlobLocator().truncate( 1 );
+ entity.getBlobLocator().setBytes( 1, changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getBlobLocator() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( changed, extractData( entity.getBlobLocator() ) );
+ entity.getBlobLocator().truncate( 1 );
+ entity.getBlobLocator().setBytes( 1, original );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ // test mutation via supplying a new clob locator instance...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getBlobLocator() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( original, extractData( entity.getBlobLocator() ) );
+ entity.setBlobLocator( Hibernate.createBlob( changed ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( changed, extractData( entity.getBlobLocator() ) );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ }
+
+ public void testUnboundedBlobLocatorAccess() throws Throwable {
+ if ( ! supportsUnboundedLobLocatorMaterialization() ) {
+ return;
+ }
+
+ // Note: unbounded mutation of the underlying lob data is completely
+ // unsupported; most databases would not allow such a construct anyway.
+ // Thus here we are only testing materialization...
+
+ byte[] original = buildRecursively( BLOB_SIZE, true );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setBlobLocator( Hibernate.createBlob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ // load the entity with the clob locator, and close the session/transaction;
+ // at that point it is unbounded...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( original, extractData( entity.getBlobLocator() ) );
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private byte[] extractData(Blob blob) throws Throwable {
+ return blob.getBytes( 1, ( int ) blob.length() );
+ }
+
+
+ private byte[] buildRecursively(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask( on );
+ for ( int i = 0; i < size; i++ ) {
+ data[i] = mask( on );
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? ( byte ) 1 : ( byte ) 0;
+ }
+
+ public static void assertEquals(byte[] val1, byte[] val2) {
+ if ( !ArrayHelper.isEquals( val1, val2 ) ) {
+ throw new AssertionFailedError( "byte arrays did not match" );
+ }
+ }
+}
Deleted: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -1,200 +0,0 @@
-package org.hibernate.test.lob;
-
-import java.sql.Blob;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
-import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class BlobTest extends DatabaseSpecificFunctionalTestCase {
- private static final int BLOB_SIZE = 10000;
-
- public BlobTest(String name) {
- super( name );
- }
-
- public String[] getMappings() {
- return new String[] { "lob/LobMappings.hbm.xml" };
- }
-
- public static Test suite() {
- return new FunctionalTestClassTestSuite( BlobTest.class );
- }
-
- public boolean appliesTo(Dialect dialect) {
- if ( ! dialect.supportsExpectedLobUsagePattern() ) {
- reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
- return false;
- }
- return true;
- }
-
- public void testBoundedMaterializedBlobAccess() {
- byte[] original = buildRecursively( BLOB_SIZE, true );
- byte[] changed = buildRecursively( BLOB_SIZE, false );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setMaterializedBlob( original );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getMaterializedBlob().length );
- assertEquals( original, entity.getMaterializedBlob() );
- entity.setMaterializedBlob( changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getMaterializedBlob().length );
- assertEquals( changed, entity.getMaterializedBlob() );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- public void testBoundedBlobLocatorAccess() throws Throwable {
- byte[] original = buildRecursively( BLOB_SIZE, true );
- byte[] changed = buildRecursively( BLOB_SIZE, false );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setBlobLocator( Hibernate.createBlob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( original, extractData( entity.getBlobLocator() ) );
- s.getTransaction().commit();
- s.close();
-
- // test mutation via setting the new clob data...
- if ( supportsLobValueChangePropogation() ) {
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- entity.getBlobLocator().truncate( 1 );
- entity.getBlobLocator().setBytes( 1, changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getBlobLocator() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( changed, extractData( entity.getBlobLocator() ) );
- entity.getBlobLocator().truncate( 1 );
- entity.getBlobLocator().setBytes( 1, original );
- s.getTransaction().commit();
- s.close();
- }
-
- // test mutation via supplying a new clob locator instance...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getBlobLocator() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( original, extractData( entity.getBlobLocator() ) );
- entity.setBlobLocator( Hibernate.createBlob( changed ) );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( changed, extractData( entity.getBlobLocator() ) );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
-
- }
-
- public void testUnboundedBlobLocatorAccess() throws Throwable {
- if ( ! supportsUnboundedLobLocatorMaterialization() ) {
- return;
- }
-
- // Note: unbounded mutation of the underlying lob data is completely
- // unsupported; most databases would not allow such a construct anyway.
- // Thus here we are only testing materialization...
-
- byte[] original = buildRecursively( BLOB_SIZE, true );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setBlobLocator( Hibernate.createBlob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- // load the entity with the clob locator, and close the session/transaction;
- // at that point it is unbounded...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- s.getTransaction().commit();
- s.close();
-
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( original, extractData( entity.getBlobLocator() ) );
-
- s = openSession();
- s.beginTransaction();
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- private byte[] extractData(Blob blob) throws Throwable {
- return blob.getBytes( 1, ( int ) blob.length() );
- }
-
-
- private byte[] buildRecursively(int size, boolean on) {
- byte[] data = new byte[size];
- data[0] = mask( on );
- for ( int i = 0; i < size; i++ ) {
- data[i] = mask( on );
- on = !on;
- }
- return data;
- }
-
- private byte mask(boolean on) {
- return on ? ( byte ) 1 : ( byte ) 0;
- }
-
- public static void assertEquals(byte[] val1, byte[] val2) {
- if ( !ArrayHelper.isEquals( val1, val2 ) ) {
- throw new AssertionFailedError( "byte arrays did not match" );
- }
- }
-}
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,190 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import java.sql.Clob;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests lazy materialization of data mapped by
+ * {@link org.hibernate.type.ClobType} as well as bounded and unbounded
+ * materialization and mutation.
+ *
+ * @author Steve Ebersole
+ */
+public class ClobLocatorTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int CLOB_SIZE = 10000;
+
+ public ClobLocatorTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/LobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( ClobLocatorTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+
+ public void testBoundedClobLocatorAccess() throws Throwable {
+ String original = buildRecursively( CLOB_SIZE, 'x' );
+ String changed = buildRecursively( CLOB_SIZE, 'y' );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setClobLocator( Hibernate.createClob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( original, extractData( entity.getClobLocator() ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // test mutation via setting the new clob data...
+ if ( supportsLobValueChangePropogation() ) {
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ entity.getClobLocator().truncate( 1 );
+ entity.getClobLocator().setString( 1, changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getClobLocator() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( changed, extractData( entity.getClobLocator() ) );
+ entity.getClobLocator().truncate( 1 );
+ entity.getClobLocator().setString( 1, original );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ // test mutation via supplying a new clob locator instance...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getClobLocator() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( original, extractData( entity.getClobLocator() ) );
+ entity.setClobLocator( Hibernate.createClob( changed ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( changed, extractData( entity.getClobLocator() ) );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ }
+
+ public void testUnboundedClobLocatorAccess() throws Throwable {
+ if ( ! supportsUnboundedLobLocatorMaterialization() ) {
+ return;
+ }
+
+ // Note: unbounded mutation of the underlying lob data is completely
+ // unsupported; most databases would not allow such a construct anyway.
+ // Thus here we are only testing materialization...
+
+ String original = buildRecursively( CLOB_SIZE, 'x' );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setClobLocator( Hibernate.createClob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ // load the entity with the clob locator, and close the session/transaction;
+ // at that point it is unbounded...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( original, extractData( entity.getClobLocator() ) );
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private String extractData(Clob clob) throws Throwable {
+ if ( getDialect() instanceof H2Dialect ) {
+ return clob.getSubString( 1, ( int ) clob.length() );
+ }
+ else {
+ char[] data = new char[ (int) clob.length() ];
+ clob.getCharacterStream().read( data );
+ return new String( data );
+ }
+ }
+
+
+ private String buildRecursively(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for( int i = 0; i < size; i++ ) {
+ buff.append( baseChar );
+ }
+ return buff.toString();
+ }
+}
Deleted: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -1,196 +0,0 @@
-package org.hibernate.test.lob;
-
-import java.sql.Clob;
-
-import junit.framework.Test;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.H2Dialect;
-import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
-import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
-
-/**
- * Test various access scenarios for eager and lazy materialization
- * of CLOB data, as well as bounded and unbounded materialization
- * and mutation.
- *
- * @author Steve Ebersole
- */
-public class ClobTest extends DatabaseSpecificFunctionalTestCase {
- private static final int CLOB_SIZE = 10000;
-
- public ClobTest(String name) {
- super( name );
- }
-
- public String[] getMappings() {
- return new String[] { "lob/LobMappings.hbm.xml" };
- }
-
- public static Test suite() {
- return new FunctionalTestClassTestSuite( ClobTest.class );
- }
-
- public boolean appliesTo(Dialect dialect) {
- if ( ! dialect.supportsExpectedLobUsagePattern() ) {
- reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
- return false;
- }
- return true;
- }
-
- public void testBoundedMaterializedClobAccess() {
- String original = buildRecursively( CLOB_SIZE, 'x' );
- String changed = buildRecursively( CLOB_SIZE, 'y' );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setMaterializedClob( original );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getMaterializedClob().length() );
- assertEquals( original, entity.getMaterializedClob() );
- entity.setMaterializedClob( changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getMaterializedClob().length() );
- assertEquals( changed, entity.getMaterializedClob() );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- public void testBoundedClobLocatorAccess() throws Throwable {
- String original = buildRecursively( CLOB_SIZE, 'x' );
- String changed = buildRecursively( CLOB_SIZE, 'y' );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setClobLocator( Hibernate.createClob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( original, extractData( entity.getClobLocator() ) );
- s.getTransaction().commit();
- s.close();
-
- // test mutation via setting the new clob data...
- if ( supportsLobValueChangePropogation() ) {
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- entity.getClobLocator().truncate( 1 );
- entity.getClobLocator().setString( 1, changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getClobLocator() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( changed, extractData( entity.getClobLocator() ) );
- entity.getClobLocator().truncate( 1 );
- entity.getClobLocator().setString( 1, original );
- s.getTransaction().commit();
- s.close();
- }
-
- // test mutation via supplying a new clob locator instance...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getClobLocator() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( original, extractData( entity.getClobLocator() ) );
- entity.setClobLocator( Hibernate.createClob( changed ) );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( changed, extractData( entity.getClobLocator() ) );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
-
- }
-
- public void testUnboundedClobLocatorAccess() throws Throwable {
- if ( ! supportsUnboundedLobLocatorMaterialization() ) {
- return;
- }
-
- // Note: unbounded mutation of the underlying lob data is completely
- // unsupported; most databases would not allow such a construct anyway.
- // Thus here we are only testing materialization...
-
- String original = buildRecursively( CLOB_SIZE, 'x' );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setClobLocator( Hibernate.createClob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- // load the entity with the clob locator, and close the session/transaction;
- // at that point it is unbounded...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- s.getTransaction().commit();
- s.close();
-
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( original, extractData( entity.getClobLocator() ) );
-
- s = openSession();
- s.beginTransaction();
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- private String extractData(Clob clob) throws Throwable {
- if ( getDialect() instanceof H2Dialect ) {
- return clob.getSubString( 1, ( int ) clob.length() );
- }
- else {
- char[] data = new char[ (int) clob.length() ];
- clob.getCharacterStream().read( data );
- return new String( data );
- }
- }
-
-
- private String buildRecursively(int size, char baseChar) {
- StringBuffer buff = new StringBuffer();
- for( int i = 0; i < size; i++ ) {
- buff.append( baseChar );
- }
- return buff.toString();
- }
-}
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongByteArrayHolder" table="LOB_ENTITY_IMAGE">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longByteArray" column="LONG_BYTE_ARRAY" type="image" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,51 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.ImageType}.
+ *
+ * @author Gail Badner
+ */
+public class ImageTest extends LongByteArrayTest {
+
+ public ImageTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/ImageMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( ImageTest.class );
+ }
+}
\ No newline at end of file
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -1,27 +1,15 @@
package org.hibernate.test.lob;
-import java.io.Serializable;
import java.sql.Blob;
import java.sql.Clob;
/**
* An entity containing all kinds of good LOB-type data...
* <p/>
- * {@link #serialData} is used to hold general serializable data which is
- * mapped via the {@link org.hibernate.type.SerializableType}.
- * <p/>
- * {@link #materializedClob} is used to hold CLOB data that is materialized
- * into a String immediately; it is mapped via the
- * {@link org.hibernate.type.TextType}.
- * <p/>
* {@link #clobLocator} is used to hold CLOB data that is materialized lazily
* via a JDBC CLOB locator; it is mapped via the
* {@link org.hibernate.type.ClobType}
* <p/>
- * {@link #materializedBlob} is used to hold BLOB data that is materialized
- * into a byte array immediately; it is mapped via the
- * {@link org.hibernate.test.lob.MaterializedBlobType}.
- * <p/>
* {@link #blobLocator} is used to hold BLOB data that is materialized lazily
* via a JDBC BLOB locator; it is mapped via the
* {@link org.hibernate.type.BlobType}
@@ -32,12 +20,8 @@
public class LobHolder {
private Long id;
- private Serializable serialData;
-
- private String materializedClob;
private Clob clobLocator;
- private byte[] materializedBlob;
private Blob blobLocator;
public Long getId() {
@@ -48,22 +32,6 @@
this.id = id;
}
- public Serializable getSerialData() {
- return serialData;
- }
-
- public void setSerialData(Serializable serialData) {
- this.serialData = serialData;
- }
-
- public String getMaterializedClob() {
- return materializedClob;
- }
-
- public void setMaterializedClob(String materializedClob) {
- this.materializedClob = materializedClob;
- }
-
public Clob getClobLocator() {
return clobLocator;
}
@@ -72,14 +40,6 @@
this.clobLocator = clobLocator;
}
- public byte[] getMaterializedBlob() {
- return materializedBlob;
- }
-
- public void setMaterializedBlob(byte[] materializedBlob) {
- this.materializedBlob = materializedBlob;
- }
-
public Blob getBlobLocator() {
return blobLocator;
}
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -10,13 +10,9 @@
<generator class="increment"/>
</id>
- <property name="serialData" column="SER_DATA" type="serializable"/>
+ <property name="clobLocator" column="CLOB_DATA" type="clob" length="15000" />
- <property name="materializedClob" column="MAT_CLOB_DATA" type="text" length="15000"/>
- <property name="clobLocator" column="CLOB_DATA" type="clob" length="15000"/>
-
- <property name="materializedBlob" column="MAT_BLOB_DATA" type="org.hibernate.test.lob.MaterializedBlobType" length="15000"/>
- <property name="blobLocator" column="BLOB_DATA" type="blob" length="15000"/>
+ <property name="blobLocator" column="BLOB_DATA" type="blob" length="15000" />
</class>
</hibernate-mapping>
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,54 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+/**
+ * An entity containing data that is materialized into a byte array immediately.
+ * The hibernate type mapped for {@link #longByteArray} determines the SQL type
+ * asctually used.
+ *
+ * @author Gail Badner
+ */
+public class LongByteArrayHolder {
+ private Long id;
+ private byte[] longByteArray;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public byte[] getLongByteArray() {
+ return longByteArray;
+ }
+
+ public void setLongByteArray(byte[] longByteArray) {
+ this.longByteArray = longByteArray;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,110 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import junit.framework.AssertionFailedError;
+import org.hibernate.Session;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Tests eager materialization and mutation of long byte arrays.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class LongByteArrayTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int ARRAY_SIZE = 10000;
+
+ public LongByteArrayTest(String name) {
+ super( name );
+ }
+
+ public void testBoundedLongByteArrayAccess() {
+ byte[] original = buildRecursively( ARRAY_SIZE, true );
+ byte[] changed = buildRecursively( ARRAY_SIZE, false );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LongByteArrayHolder entity = new LongByteArrayHolder();
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertNull( entity.getLongByteArray() );
+ entity.setLongByteArray( original );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
+ assertEquals( original, entity.getLongByteArray() );
+ entity.setLongByteArray( changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
+ assertEquals( changed, entity.getLongByteArray() );
+ entity.setLongByteArray( null );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertNull( entity.getLongByteArray() );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private byte[] buildRecursively(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask( on );
+ for ( int i = 0; i < size; i++ ) {
+ data[i] = mask( on );
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? ( byte ) 1 : ( byte ) 0;
+ }
+
+ public static void assertEquals(byte[] val1, byte[] val2) {
+ if ( !ArrayHelper.isEquals( val1, val2 ) ) {
+ throw new AssertionFailedError( "byte arrays did not match" );
+ }
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,53 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+/**
+ * An entity containing data that is materialized into a String immediately.
+ *
+ * @author Gail Badner
+ */
+public class LongStringHolder {
+ private Long id;
+
+ private String longString;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getLongString() {
+ return longString;
+ }
+
+ public void setLongString(String longString) {
+ this.longString = longString;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,99 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.Session;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests eager materialization and mutation of long strings.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class LongStringTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int LONG_STRING_SIZE = 10000;
+
+ public LongStringTest(String name) {
+ super( name );
+ }
+
+ public void testBoundedLongStringAccess() {
+ String original = buildRecursively( LONG_STRING_SIZE, 'x' );
+ String changed = buildRecursively( LONG_STRING_SIZE, 'y' );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LongStringHolder entity = new LongStringHolder();
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertNull( entity.getLongString() );
+ entity.setLongString( original );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
+ assertEquals( original, entity.getLongString() );
+ entity.setLongString( changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
+ assertEquals( changed, entity.getLongString() );
+ entity.setLongString( null );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertNull( entity.getLongString() );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private String buildRecursively(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for( int i = 0; i < size; i++ ) {
+ buff.append( baseChar );
+ }
+ return buff.toString();
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongByteArrayHolder" table="LOB_ENTITY_MAT_BLOB">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longByteArray" column="LONG_BYTE_ARRAY" type="materialized_blob" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,60 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.MaterializedBlobType}.
+ *
+ * @author Gail Badner
+ */
+public class MaterializedBlobTest extends LongByteArrayTest {
+
+ public MaterializedBlobTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/MaterializedBlobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( MaterializedBlobTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongStringHolder" table="LOB_ENTITY_MAT_CLOB">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longString" column="LONG_STR" type="materialized_clob" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,60 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.MaterializedClobType}.
+ *
+ * @author Gail Badner
+ */
+public class MaterializedClobTest extends LongStringTest {
+
+ public MaterializedClobTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/MaterializedClobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( MaterializedClobTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,56 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import java.io.Serializable;
+
+/**
+ * An entity containing serializable data which is
+ * mapped via the {@link org.hibernate.type.SerializableType}.
+ *
+ * @author Steve Ebersole
+ */
+public class SerializableHolder {
+ private Long id;
+
+ private Serializable serialData;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Serializable getSerialData() {
+ return serialData;
+ }
+
+ public void setSerialData(Serializable serialData) {
+ this.serialData = serialData;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="SerializableHolder" table="LOB_ENTITY">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="serialData" column="SER_DATA" type="serializable"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -4,10 +4,6 @@
import junit.framework.Test;
import org.hibernate.Session;
-import org.hibernate.dialect.Sybase11Dialect;
-import org.hibernate.dialect.SybaseASE15Dialect;
-import org.hibernate.dialect.SybaseAnywhereDialect;
-import org.hibernate.dialect.SybaseDialect;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -23,7 +19,7 @@
}
public String[] getMappings() {
- return new String[] { "lob/LobMappings.hbm.xml" };
+ return new String[] { "lob/SerializableMappings.hbm.xml" };
}
public static Test suite() {
@@ -36,30 +32,49 @@
}
public void testNewSerializableType() {
- // Sybase dialects do not support ResultSet.getBlob(String)
- if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect ) {
- return;
- }
+ final String initialPayloadText = "Initial payload";
+ final String changedPayloadText = "Changed payload";
- final String payloadText = "Initial payload";
-
Session s = openSession();
s.beginTransaction();
- LobHolder holder = new LobHolder();
- holder.setSerialData( new SerializableData( payloadText ) );
+ SerializableHolder holder = new SerializableHolder();
s.save( holder );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
- holder = ( LobHolder ) s.get( LobHolder.class, holder.getId() );
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
+ assertNull( holder.getSerialData() );
+ holder.setSerialData( new SerializableData( initialPayloadText ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
SerializableData serialData = ( SerializableData ) holder.getSerialData();
- assertEquals( payloadText, serialData.getPayload() );
+ assertEquals( initialPayloadText, serialData.getPayload() );
+ holder.setSerialData( new SerializableData( changedPayloadText ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
+ serialData = ( SerializableData ) holder.getSerialData();
+ assertEquals( changedPayloadText, serialData.getPayload() );
+ holder.setSerialData( null );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
+ assertNull( holder.getSerialData() );
s.delete( holder );
s.getTransaction().commit();
s.close();
}
-
}
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongStringHolder" table="LOB_ENTITY_TEXT">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longString" column="LONG_STR" type="text" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,51 @@
+//$Id: $
+/*
+ * 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.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Test eager materialization and mutation data mapped by
+ * #{@link org.hibernate.type.TextType}.
+ *
+ * @author Gail Badner
+ */
+public class TextTest extends LongStringTest {
+
+ public TextTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/TextMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( TextTest.class );
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/ImageHolder.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/ImageHolder.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/ImageHolder.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 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.test.sql.hand;
+
+/**
+ * @author Gail Badner
+ */
+public class ImageHolder {
+ private Long id;
+ private byte[] photo;
+
+ public ImageHolder(byte[] photo) {
+ this.photo = photo;
+ }
+
+ public ImageHolder() {
+ }
+
+ /**
+ * @return Returns the id.
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * @param id The id to set.
+ */
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ /**
+ * @return Returns the photo.
+ */
+ public byte[] getPhoto() {
+ return photo;
+ }
+
+ /**
+ * @param photo The photo to set.
+ */
+ public void setPhoto(byte[] photo) {
+ this.photo = photo;
+ }
+}
\ No newline at end of file
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/TextHolder.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/TextHolder.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/TextHolder.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 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.test.sql.hand;
+
+/**
+ * @author Gail Badner
+ */
+public class TextHolder {
+ private Long id;
+ private String description;
+
+ public TextHolder(String description) {
+ this.description = description;
+ }
+
+ public TextHolder() {
+ }
+
+ /**
+ * @return Returns the id.
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * @param id The id to set.
+ */
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ /**
+ * @return Returns the description.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * @param description The description to set.
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
\ No newline at end of file
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -9,8 +9,11 @@
import org.hibernate.Transaction;
import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
import org.hibernate.test.sql.hand.Employment;
+import org.hibernate.test.sql.hand.ImageHolder;
import org.hibernate.test.sql.hand.Organization;
import org.hibernate.test.sql.hand.Person;
+import org.hibernate.test.sql.hand.TextHolder;
+import org.hibernate.util.ArrayHelper;
/**
* Abstract test case defining tests for the support for user-supplied (aka
@@ -91,4 +94,81 @@
s.close();
}
+ public void testTextProperty() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ String description = buildLongString( 15000, 'a' );
+ TextHolder holder = new TextHolder( description );
+ s.save( holder );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ holder = ( TextHolder ) s.get( TextHolder.class, holder.getId() );
+ assertEquals( description, holder.getDescription() );
+ description = buildLongString( 15000, 'b' );
+ holder.setDescription( description );
+ s.save( holder );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ holder = ( TextHolder ) s.get( TextHolder.class, holder.getId() );
+ assertEquals( description, holder.getDescription() );
+ s.delete( holder );
+ t.commit();
+ s.close();
+ }
+
+ public void testImageProperty() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ byte[] photo = buildLongByteArray( 15000, true );
+ ImageHolder holder = new ImageHolder( photo );
+ s.save( holder );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ holder = ( ImageHolder ) s.get( ImageHolder.class, holder.getId() );
+ assertTrue( ArrayHelper.isEquals( photo, holder.getPhoto() ) );
+ photo = buildLongByteArray( 15000, false );
+ holder.setPhoto( photo );
+ s.save( holder );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ holder = ( ImageHolder ) s.get( ImageHolder.class, holder.getId() );
+ assertTrue( ArrayHelper.isEquals( photo, holder.getPhoto() ) );
+ s.delete( holder );
+ t.commit();
+ s.close();
+ }
+
+ private String buildLongString(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for( int i = 0; i < size; i++ ) {
+ buff.append( baseChar );
+ }
+ return buff.toString();
+ }
+
+ private byte[] buildLongByteArray(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask( on );
+ for ( int i = 0; i < size; i++ ) {
+ data[i] = mask( on );
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? ( byte ) 1 : ( byte ) 0;
+ }
}
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/db2/Mappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/db2/Mappings.hbm.xml 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/db2/Mappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -64,7 +64,35 @@
<sql-update>UPDATE EMPLOYMENT SET ENDDATE=?, VALUE=?, CURRENCY=? WHERE EMPID=?</sql-update>
<sql-delete>DELETE FROM EMPLOYMENT WHERE EMPID=?</sql-delete>
</class>
+ <class name="TextHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" type="text" length="15000"/>
+ <loader query-ref="textholder"/>
+ <sql-insert>
+ INSERT INTO TEXTHOLDER
+ (DESCRIPTION, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE TEXTHOLDER SET DESCRIPTION=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM TEXTHOLDER WHERE ID=?</sql-delete>
+ </class>
+ <class name="ImageHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="photo" type="image" length="15000"/>
+ <loader query-ref="imageholder"/>
+ <sql-insert>
+ INSERT INTO IMAGEHOLDER
+ (PHOTO, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE IMAGEHOLDER SET PHOTO=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM IMAGEHOLDER WHERE ID=?</sql-delete>
+ </class>
<resultset name="org-emp-regionCode">
<return-scalar column="regionCode" type="string"/>
<return alias="org" class="Organization"/>
@@ -182,7 +210,15 @@
</return>
{ call HIBDB2TST.selectAllEmployments() }
</sql-query>
+ <sql-query name="textholder">
+ <return alias="h" class="TextHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, DESCRIPTION AS {h.description} FROM TEXTHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
+ <sql-query name="imageholder">
+ <return alias="h" class="ImageHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, PHOTO AS {h.photo} FROM IMAGEHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
<!-- DB2 seem to *require* users to specify explicit schema/location when executing a stored procedure *stupid* -->
<database-object>
<create>CREATE SCHEMA HIBDB2TST</create>
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/mysql/Mappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/mysql/Mappings.hbm.xml 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/mysql/Mappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -65,6 +65,36 @@
<sql-delete>DELETE FROM Employment WHERE EMPID=?</sql-delete>
</class>
+ <class name="TextHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" type="text" length="15000"/>
+ <loader query-ref="textholder"/>
+ <sql-insert>
+ INSERT INTO TextHolder
+ (DESCRIPTION, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE TextHolder SET DESCRIPTION=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM TextHolder WHERE ID=?</sql-delete>
+ </class>
+
+ <class name="ImageHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="photo" type="image" length="15000"/>
+ <loader query-ref="imageholder"/>
+ <sql-insert>
+ INSERT INTO ImageHolder
+ (PHOTO, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE ImageHolder SET PHOTO=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM ImageHolder WHERE ID=?</sql-delete>
+ </class>
+
<resultset name="org-emp-regionCode">
<return-scalar column="regionCode" type="string"/>
<return alias="org" class="Organization"/>
@@ -180,7 +210,15 @@
</return>
{ call selectAllEmployments() }
</sql-query>
-
+ <sql-query name="textholder">
+ <return alias="h" class="TextHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, DESCRIPTION AS {h.description} FROM TextHolder WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
+
+ <sql-query name="imageholder">
+ <return alias="h" class="ImageHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, PHOTO AS {h.photo} FROM ImageHolder WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
<database-object>
<create>
CREATE PROCEDURE selectAllEmployments ()
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/oracle/Mappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/oracle/Mappings.hbm.xml 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/oracle/Mappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -65,6 +65,36 @@
<sql-delete>DELETE FROM EMPLOYMENT WHERE EMPID=?</sql-delete>
</class>
+ <class name="TextHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" type="text" length="15000"/>
+ <loader query-ref="textholder"/>
+ <sql-insert>
+ INSERT INTO TEXTHOLDER
+ (DESCRIPTION, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE TEXTHOLDER SET DESCRIPTION=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM TEXTHOLDER WHERE ID=?</sql-delete>
+ </class>
+
+ <class name="ImageHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="photo" type="image" length="15000"/>
+ <loader query-ref="imageholder"/>
+ <sql-insert>
+ INSERT INTO IMAGEHOLDER
+ (PHOTO, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE IMAGEHOLDER SET PHOTO=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM IMAGEHOLDER WHERE ID=?</sql-delete>
+ </class>
+
<resultset name="org-emp-regionCode">
<return-scalar column="regionCode" type="string"/>
<return alias="org" class="Organization"/>
@@ -138,7 +168,15 @@
WHERE EMPLOYER = :id AND ENDDATE IS NULL
ORDER BY STARTDATE ASC
</sql-query>
+ <sql-query name="textholder">
+ <return alias="h" class="TextHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, DESCRIPTION AS {h.description} FROM TEXTHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
+ <sql-query name="imageholder">
+ <return alias="h" class="ImageHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, PHOTO AS {h.photo} FROM IMAGEHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
<database-object>
<create>
CREATE OR REPLACE FUNCTION testParamHandling (j number, i number)
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/Mappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/Mappings.hbm.xml (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/Mappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,287 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+ This mapping demonstrates the use of Hibernate with all-handwritten SQL!
+
+ NOTE: this version is for SQLServer
+-->
+<hibernate-mapping package="org.hibernate.test.sql.hand" default-access="field">
+
+ <class name="Organization" table="ORGANIZATION">
+ <id name="id" unsaved-value="0" column="ORGID">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true" column="NAME"/>
+ <set name="employments"
+ inverse="true"
+ order-by="DUMMY">
+ <key column="EMPLOYER"/> <!-- only needed for DDL generation -->
+ <one-to-many class="Employment"/>
+ <loader query-ref="organizationEmployments"/>
+ </set>
+ <!-- query-list name="currentEmployments"
+ query-ref="organizationCurrentEmployments"-->
+ <loader query-ref="organization"/>
+ <sql-insert>INSERT INTO ORGANIZATION (NAME, ORGID) VALUES ( UPPER(?), ? )</sql-insert>
+ <sql-update>UPDATE ORGANIZATION SET NAME=UPPER(?) WHERE ORGID=?</sql-update>
+ <sql-delete>DELETE FROM ORGANIZATION WHERE ORGID=?</sql-delete>
+ </class>
+
+ <class name="Person" table="PERSON">
+ <id name="id" unsaved-value="0" column="PERID">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true" column="NAME"/>
+ <loader query-ref="person"/>
+ <sql-insert>INSERT INTO PERSON (NAME, PERID) VALUES ( UPPER(?), ? )</sql-insert>
+ <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE PERID=?</sql-update>
+ <sql-delete>DELETE FROM PERSON WHERE PERID=?</sql-delete>
+ </class>
+
+ <class name="Employment" table="EMPLOYMENT">
+ <id name="employmentId" unsaved-value="0" column="EMPID">
+ <generator class="increment"/>
+ </id>
+ <many-to-one name="employee" column="EMPLOYEE" not-null="true" update="false"/>
+ <many-to-one name="employer" column="EMPLOYER" not-null="true" update="false"/>
+ <property name="startDate" column="STARTDATE" not-null="true" update="false" insert="false"/>
+ <property name="endDate" column="ENDDATE" insert="false"/>
+ <property name="regionCode" column="REGIONCODE" update="false"/>
+ <property name="salary" type="org.hibernate.test.sql.hand.MonetaryAmountUserType">
+ <column name="VALUE" sql-type="float"/>
+ <column name="CURRENCY"/>
+ </property>
+ <loader query-ref="employment"/>
+ <sql-insert>
+ INSERT INTO EMPLOYMENT
+ (EMPLOYEE, EMPLOYER, STARTDATE, REGIONCODE, VALUE, CURRENCY, EMPID)
+ VALUES (?, ?, getdate(), UPPER(?), ?, ?, ?)
+ </sql-insert>
+ <sql-update>UPDATE EMPLOYMENT SET ENDDATE=?, VALUE=?, CURRENCY=? WHERE EMPID=?</sql-update>
+ <sql-delete>DELETE FROM EMPLOYMENT WHERE EMPID=?</sql-delete>
+ </class>
+
+ <class name="TextHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" type="text" length="15000"/>
+ <loader query-ref="textholder"/>
+ <sql-insert>
+ INSERT INTO TEXTHOLDER
+ (DESCRIPTION, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE TEXTHOLDER SET DESCRIPTION=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM TEXTHOLDER WHERE ID=?</sql-delete>
+ </class>
+
+ <class name="ImageHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="photo" type="image" length="15000"/>
+ <loader query-ref="imageholder"/>
+ <sql-insert>
+ INSERT INTO IMAGEHOLDER
+ (PHOTO, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE IMAGEHOLDER SET PHOTO=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM IMAGEHOLDER WHERE ID=?</sql-delete>
+ </class>
+
+ <resultset name="org-emp-regionCode">
+ <return-scalar column="regionCode" type="string"/>
+ <return alias="org" class="Organization"/>
+ <return-join alias="emp" property="org.employments"/>
+ </resultset>
+
+ <resultset name="org-emp-person">
+ <return alias="org" class="Organization"/>
+ <return-join alias="emp" property="org.employments"/>
+ <return-join alias="pers" property="emp.employee"/>
+ </resultset>
+
+ <sql-query name="person">
+ <return alias="p" class="Person" lock-mode="upgrade"/>
+ SELECT NAME AS {p.name}, PERID AS {p.id} FROM PERSON WHERE PERID=? /*FOR UPDATE*/
+ </sql-query>
+
+ <sql-query name="organization">
+ <return alias="org" class="Organization"/>
+ <return-join alias="emp" property="org.employments"/>
+ SELECT {org.*}, {emp.*}
+ FROM ORGANIZATION org
+ LEFT OUTER JOIN EMPLOYMENT emp ON org.ORGID = emp.EMPLOYER
+ WHERE org.ORGID=?
+ </sql-query>
+
+
+ <!--sql-query name="organization">
+ <return alias="org" class="Organization"/>
+ SELECT NAME AS {org.name}, ORGID AS {org.id} FROM ORGANIZATION
+ WHERE ORGID=?
+ </sql-query-->
+
+ <sql-query name="allOrganizationsWithEmployees" flush-mode="never">
+ <return alias="org" class="Organization"/>
+ SELECT DISTINCT org.NAME AS {org.name}, org.ORGID AS {org.id}
+ FROM ORGANIZATION org
+ INNER JOIN EMPLOYMENT e ON e.EMPLOYER = org.ORGID
+ </sql-query>
+
+
+
+
+
+ <sql-query name="employment">
+ <return alias="emp" class="Employment"/>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EMPID AS {emp.id}
+ FROM EMPLOYMENT
+ WHERE EMPID = ?
+ </sql-query>
+
+ <sql-query name="organizationEmployments">
+ <load-collection alias="empcol" role="Organization.employments"/>
+ SELECT {empcol.*}
+ FROM EMPLOYMENT empcol
+ WHERE EMPLOYER = :id
+ ORDER BY STARTDATE ASC, EMPLOYEE ASC
+ </sql-query>
+
+
+ <sql-query name="organizationCurrentEmployments">
+ <return alias="emp" class="Employment">
+ <return-property name="salary">
+ <!-- as multi column properties are not supported via the
+ {}-syntax, we need to provide an explicit column list for salary via <return-property> -->
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ <!-- Here we are remapping endDate. Notice that we can still use {emp.endDate} in the SQL. -->
+ <return-property name="endDate" column="myEndDate"/>
+ </return>
+ <synchronize table="EMPLOYMENT"/>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EMPID AS {emp.id}, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ WHERE EMPLOYER = :id AND ENDDATE IS NULL
+ ORDER BY STARTDATE ASC
+ </sql-query>
+
+ <sql-query name="simpleScalar" callable="true">
+ <return-scalar column="name" type="string"/>
+ <return-scalar column="value" type="long"/>
+ { call simpleScalar(:number) }
+ </sql-query>
+
+ <sql-query name="paramhandling" callable="true">
+ <return-scalar column="value" type="long"/>
+ <return-scalar column="value2" type="long"/>
+ { call paramHandling(?,?) }
+ </sql-query>
+
+ <sql-query name="paramhandling_mixed" callable="true">
+ <return-scalar column="value" type="long" />
+ <return-scalar column="value2" type="long" />
+ { call paramHandling(?,:second) }
+ </sql-query>
+
+ <sql-query name="selectAllEmployments" callable="true">
+ <return alias="" class="Employment">
+ <return-property name="employee" column="EMPLOYEE"/>
+ <return-property name="employer" column="EMPLOYER"/>
+ <return-property name="startDate" column="STARTDATE"/>
+ <return-property name="endDate" column="ENDDATE"/>
+ <return-property name="regionCode" column="REGIONCODE"/>
+ <return-property name="id" column="EMPID"/>
+ <return-property name="salary">
+ <!-- as multi column properties are not supported via the
+ {}-syntax, we need to provide an explicit column list for salary via <return-property> -->
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ </return>
+ { call selectAllEmployments() }
+ </sql-query>
+
+ <sql-query name="textholder">
+ <return alias="h" class="TextHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, DESCRIPTION AS {h.description} FROM TEXTHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
+
+ <sql-query name="imageholder">
+ <return alias="h" class="ImageHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, PHOTO AS {h.photo} FROM IMAGEHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
+
+ <database-object>
+ <create>
+ CREATE PROCEDURE selectAllEmployments AS
+ SELECT EMPLOYEE, EMPLOYER, STARTDATE, ENDDATE,
+ REGIONCODE, EMPID, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ </create>
+ <drop>
+ DROP PROCEDURE selectAllEmployments
+ </drop>
+ </database-object>
+
+ <!-- The following is a workaround for HHH-3685 so that SchemaExport -->
+ <!-- changes the transaction mode of selectAllEmployments to "chained" -->
+ <database-object>
+ <create>
+ sp_procxmode selectAllEmployments, 'chained'
+ </create>
+ <!-- no drop command corresponding to "sp_procxmode ..." -->
+ <drop/>
+ </database-object>
+
+ <database-object>
+ <create>
+ CREATE PROCEDURE paramHandling @j int, @i int AS
+ SELECT @j as value, @i as value2
+ </create>
+ <drop>
+ DROP PROCEDURE paramHandling
+ </drop>
+ </database-object>
+
+ <!-- The following is a workaround for HHH-3685 so that SchemaExport -->
+ <!-- changes the transaction mode of paramHandling to "chained" -->
+ <database-object>
+ <create>
+ sp_procxmode paramHandling, 'chained'
+ </create>
+ <!-- no drop command corresponding to "sp_procxmode ..." -->
+ <drop/>
+ </database-object>
+
+ <database-object>
+ <create>
+ CREATE PROCEDURE simpleScalar @number int AS
+ SELECT @number as value, 'getAll' as name
+ </create>
+ <drop>
+ DROP PROCEDURE simpleScalar
+ </drop>
+ </database-object>
+
+ <!-- The following is a workaround for HHH-3685 so that SchemaExport -->
+ <!-- changes the transaction mode of simpleScalar to "chained" -->
+ <database-object>
+ <create>
+ sp_procxmode simpleScalar, 'chained'
+ </create>
+ <!-- no drop command corresponding to "sp_procxmode ..." -->
+ <drop/>
+ </database-object>
+
+</hibernate-mapping>
Added: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/SQLServerCustomSQLTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/SQLServerCustomSQLTest.java (rev 0)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sqlserver/SQLServerCustomSQLTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 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.test.sql.hand.custom.sqlserver;
+
+import junit.framework.Test;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.sql.hand.custom.CustomStoredProcTestSupport;
+
+/**
+ * Custom SQL tests for SQLServer
+ *
+ * @author Gail Badner
+ */
+public class SQLServerCustomSQLTest extends CustomStoredProcTestSupport {
+
+ public SQLServerCustomSQLTest(String str) {
+ super( str );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "sql/hand/custom/sqlserver/Mappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( SQLServerCustomSQLTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ return ( dialect instanceof SQLServerDialect );
+ }
+}
\ No newline at end of file
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/Mappings.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/Mappings.hbm.xml 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/Mappings.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -64,6 +64,36 @@
<sql-delete>DELETE FROM EMPLOYMENT WHERE EMPID=?</sql-delete>
</class>
+ <class name="TextHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" type="text" length="15000"/>
+ <loader query-ref="textholder"/>
+ <sql-insert>
+ INSERT INTO TEXTHOLDER
+ (DESCRIPTION, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE TEXTHOLDER SET DESCRIPTION=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM TEXTHOLDER WHERE ID=?</sql-delete>
+ </class>
+
+ <class name="ImageHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="photo" type="image" length="15000"/>
+ <loader query-ref="imageholder"/>
+ <sql-insert>
+ INSERT INTO IMAGEHOLDER
+ (PHOTO, ID)
+ VALUES (?, ?)
+ </sql-insert>
+ <sql-update>UPDATE IMAGEHOLDER SET PHOTO=? WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM IMAGEHOLDER WHERE ID=?</sql-delete>
+ </class>
+
<resultset name="org-emp-regionCode">
<return-scalar column="regionCode" type="string"/>
<return alias="org" class="Organization"/>
@@ -182,6 +212,15 @@
{ call selectAllEmployments() }
</sql-query>
+ <sql-query name="textholder">
+ <return alias="h" class="TextHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, DESCRIPTION AS {h.description} FROM TEXTHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
+
+ <sql-query name="imageholder">
+ <return alias="h" class="ImageHolder" lock-mode="upgrade"/>
+ SELECT ID AS {h.id}, PHOTO AS {h.photo} FROM IMAGEHOLDER WHERE ID=? /*FOR UPDATE*/
+ </sql-query>
<database-object>
<create>
CREATE PROCEDURE selectAllEmployments AS
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/SybaseCustomSQLTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/SybaseCustomSQLTest.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/custom/sybase/SybaseCustomSQLTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -4,12 +4,15 @@
import junit.framework.Test;
import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.sql.hand.custom.CustomStoredProcTestSupport;
/**
- * Custom SQL tests for Sybase/SQLServer (Transact-SQL)
+ * Custom SQL tests for Sybase dialect
*
* @author Gavin King
*/
@@ -28,7 +31,10 @@
}
public boolean appliesTo(Dialect dialect) {
- return ( dialect instanceof SybaseDialect );
+ return ( dialect instanceof SybaseDialect ||
+ dialect instanceof SybaseASE15Dialect ||
+ dialect instanceof Sybase11Dialect ||
+ dialect instanceof SybaseAnywhereDialect );
}
}
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml 2010-04-27 05:46:04 UTC (rev 19297)
@@ -116,6 +116,20 @@
<property name="length" column="flength"/>
</class>
+ <class name="TextHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="description" type="text" length="15000"/>
+ </class>
+
+ <class name="ImageHolder">
+ <id name="id" column="id">
+ <generator class="increment"/>
+ </id>
+ <property name="photo" type="image" length="15000"/>
+ </class>
+
<resultset name="org-emp-regionCode">
<return-scalar column="regionCode" type="string"/>
<return alias="org" class="Organization"/>
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java 2010-04-26 18:16:39 UTC (rev 19296)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java 2010-04-27 05:46:04 UTC (rev 19297)
@@ -22,15 +22,18 @@
import org.hibernate.test.sql.hand.Dimension;
import org.hibernate.test.sql.hand.Employment;
import org.hibernate.test.sql.hand.Group;
+import org.hibernate.test.sql.hand.ImageHolder;
import org.hibernate.test.sql.hand.Order;
import org.hibernate.test.sql.hand.Organization;
import org.hibernate.test.sql.hand.Person;
import org.hibernate.test.sql.hand.Product;
import org.hibernate.test.sql.hand.SpaceShip;
import org.hibernate.test.sql.hand.Speech;
+import org.hibernate.test.sql.hand.TextHolder;
import org.hibernate.transform.BasicTransformerAdapter;
import org.hibernate.transform.DistinctRootEntityResultTransformer;
import org.hibernate.transform.Transformers;
+import org.hibernate.util.ArrayHelper;
/**
* Tests of various features of native SQL queries.
@@ -94,7 +97,13 @@
" join EMPLOYMENT emp on org.ORGID = emp.EMPLOYER " +
" join PERSON pers on pers.PERID = emp.EMPLOYEE ";
}
+ protected String getDescriptionsSQL() {
+ return "select DESCRIPTION from TEXTHOLDER";
+ }
+ protected String getPhotosSQL() {
+ return "select PHOTO from IMAGEHOLDER";
+ }
public void testFailOnNoAddEntityOrScalar() {
// Note: this passes, but for the wrong reason.
// there is actually an exception thrown, but it is the database
@@ -667,6 +676,66 @@
s.close();
}
+ public void testTextTypeInSQLQuery() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ String description = buildLongString( 15000, 'a' );
+ TextHolder holder = new TextHolder( description );
+ s.persist( holder );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ String descriptionRead = ( String ) s.createSQLQuery( getDescriptionsSQL() )
+ .uniqueResult();
+ assertEquals( description, descriptionRead );
+ s.delete( holder );
+ t.commit();
+ s.close();
+ }
+
+ public void testImageTypeInSQLQuery() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ byte[] photo = buildLongByteArray( 15000, true );
+ ImageHolder holder = new ImageHolder( photo );
+ s.persist( holder );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ byte[] photoRead = ( byte[] ) s.createSQLQuery( getPhotosSQL() )
+ .uniqueResult();
+ assertTrue( ArrayHelper.isEquals( photo, photoRead ) );
+ s.delete( holder );
+ t.commit();
+ s.close();
+ }
+
+ private String buildLongString(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for( int i = 0; i < size; i++ ) {
+ buff.append( baseChar );
+ }
+ return buff.toString();
+ }
+
+ private byte[] buildLongByteArray(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask( on );
+ for ( int i = 0; i < size; i++ ) {
+ data[i] = mask( on );
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? ( byte ) 1 : ( byte ) 0;
+ }
+
private static class UpperCasedAliasToEntityMapResultTransformer extends BasicTransformerAdapter implements Serializable {
public Object transformTuple(Object[] tuple, String[] aliases) {
Map result = new HashMap( tuple.length );
14 years, 7 months
Hibernate SVN: r19296 - core/trunk/documentation/manual/src/main/docbook/en-US/content.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-26 14:16:39 -0400 (Mon, 26 Apr 2010)
New Revision: 19296
Modified:
core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml
Log:
HHH-5149 start converting the id section with new functional structure
Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml 2010-04-26 17:49:26 UTC (rev 19295)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml 2010-04-26 18:16:39 UTC (rev 19296)
@@ -430,13 +430,6 @@
<itemizedlist>
<listitem>
- <para><literal>mutable</literal> (defaults to true): Immutable
- classes, <literal>mutable=false</literal>, cannot be updated or
- deleted by the application. This allows Hibernate to make some minor
- performance optimizations.</para>
- </listitem>
-
- <listitem>
<para><literal>dynamicInsert</literal> /
<literal>dynamicUpdate</literal> (defaults to false): specifies that
<literal>INSERT</literal> / <literal>UPDATE</literal> SQL should be
@@ -535,6 +528,11 @@
accident.</para>
</tip>
+ <para>Some entities are not mutable. They cannot be updated or deleted
+ by the application. This allows Hibernate to make some minor performance
+ optimizations.. Use the <classname>@Immutable</classname>
+ annotation.</para>
+
<para>You can also alter how Hibernate deals with lazy initialization
for this class. On <classname>@Proxy</classname>, use
<literal>lazy</literal>=false to disable lazy fetching (not
@@ -548,7 +546,7 @@
<para><classname>@BatchSize</classname> specifies a "batch size" for
fetching instances of this class by identifier. Not yet loaded instances
- are loaded batch-size at a time (default 1). </para>
+ are loaded batch-size at a time (default 1).</para>
<para>You can specific an arbitrary SQL WHERE condition to be used when
retrieving objects of this class. Use <classname>@Where</classname> for
@@ -828,14 +826,25 @@
</section>
<section id="mapping-declaration-id" revision="4">
- <title>id</title>
+ <title>identifiers</title>
<para>Mapped classes <emphasis>must</emphasis> declare the primary key
column of the database table. Most classes will also have a
- JavaBeans-style property holding the unique identifier of an instance.
- The <literal><id></literal> element defines the mapping from that
- property to the primary key column.</para>
+ JavaBeans-style property holding the unique identifier of an
+ instance.</para>
+ <para>Mark the identifier property with
+ <classname>@Id</classname>.</para>
+
+ <programlisting role="JAVA">@Entity
+public class Person {
+ @Id Integer getId() { ... }
+ ...
+}</programlisting>
+
+ <para>In hbm.xml, use the <literal><id></literal> element which
+ defines the mapping from that property to the primary key column.</para>
+
<programlistingco role="XML">
<areaspec>
<area coords="2" id="id1" />
@@ -896,12 +905,447 @@
that the class has no identifier property.</para>
<para>The <literal>unsaved-value</literal> attribute is almost never
- needed in Hibernate3.</para>
+ needed in Hibernate3 and indeed has no corresponding element in
+ annotations.</para>
- <para>There is an alternative <literal><composite-id></literal>
- declaration that allows access to legacy data with composite keys. Its
- use is strongly discouraged for anything else.</para>
+ <para>You can also declare the identifier as a composite identifier.
+ This allows access to legacy data with composite keys. Its use is
+ strongly discouraged for anything else.</para>
+ <section>
+ <title>Composite identifier</title>
+
+ <para>You can define a composite primary key through several
+ syntaxes:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>use a component type to represent the identifier and map it
+ as a property in the entity: you then annotated the property as
+ <classname>@EmbeddedId</classname>. The component type has to be
+ <classname>Serializable</classname>.</para>
+ </listitem>
+
+ <listitem>
+ <para>map multiple properties as <classname>@Id</classname>
+ properties: the identifier type is then the entity class itself
+ and needs to be <classname>Serializable</classname>. This approach
+ is unfortunately not standard and only supported by
+ Hibernate.</para>
+ </listitem>
+
+ <listitem>
+ <para>map multiple properties as <classname>@Id</classname>
+ properties and declare an external class to be the identifier
+ type. This class, which needs to be
+ <classname>Serializable</classname>, is declared on the entity via
+ the <classname>@IdClass</classname> annotation. The identifier
+ type must contain the same properties as the identifier properties
+ of the entity: each property name must be the same, its type must
+ be the same as well if the entity property is of a basic type, its
+ type must be the type of the primary key of the associated entity
+ if the entity property is an association (either a
+ <classname>@OneToOne</classname> or a
+ <classname>@ManyToOne</classname>).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>As you can see the last case is far from obvious. It has been
+ inherited from the dark ages of EJB 2 for backward compatibilities and
+ we recommend you not to use it (for simplicity sake).</para>
+
+ <para>Let's explore all three cases using examples.</para>
+
+ <section>
+ <title>Property using a component type</title>
+
+ <para>Here is a simple example of
+ <classname>@EmbeddedId</classname>.</para>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+class User {
+ @EmbeddedId
+ @AttributeOverride(name="firstName", column=@Column(name="fld_firstname")
+ UserId id;
+
+ Integer age;
+}
+
+@Embeddable
+class UserId implements Serializable {
+ String firstName;
+ String lastName;
+}</programlisting>
+
+ <para>You can notice that the <classname>UserId</classname> class is
+ serializable. To override the column mapping, use
+ <classname>@AttributeOverride</classname>.</para>
+
+ <para>An embedded id can itself contains the primary key of an
+ associated entity.</para>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+class Customer {
+ @EmbeddedId CustomerId id;
+ boolean preferredCustomer;
+
+ @MapsId("userId")
+ @JoinColumns({
+ @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
+ @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
+ })
+ @OneToOne User user;
+}
+
+@Embeddable
+class CustomerId implements Serializable {
+ UserId userId;
+ String customerNumber;
+}
+
+@Entity
+class User {
+ @EmbeddedId UserId id;
+ Integer age;
+}
+
+@Embeddable
+class UserId implements Serializable {
+ String firstName;
+ String lastName;
+}</programlisting>
+
+ <para>In the embedded id object, the association is represented as
+ the identifier of the associated entity. But you can link its value
+ to a regular association in the entity via the
+ <classname>@MapsId</classname> annotation. The
+ <classname>@MapsId</classname> value correspond to the property name
+ of the embedded id object containing the associated entity's
+ identifier. In the database, it means that the
+ <literal>Customer.user</literal> and the
+ <literal>CustomerId.userId</literal> properties share the same
+ underlying column (<literal>user_fk</literal> in this case).</para>
+
+ <para>In practice, your code only sets the
+ <literal>Customer.user</literal> property and the user id value is
+ copied by Hibernate into the <literal>CustomerId.userId</literal>
+ property.</para>
+
+ <warning>
+ <para>The id value can be copied as late as flush time, don't rely
+ on it until after flush time.</para>
+ </warning>
+
+ <para>While not supported in JPA, Hibernate lets you place your
+ association directly in the embedded id component (instead of having
+ to use the <classname>@MapsId</classname> annotation).</para>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+class Customer {
+ @EmbeddedId CustomerId id;
+ boolean preferredCustomer;
+}
+
+@Embeddable
+class CustomerId implements Serializable {
+ @OneToOne
+ @JoinColumns({
+ @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
+ @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
+ })
+ User user;
+ String customerNumber;
+}
+
+@Entity
+class User {
+ @EmbeddedId UserId id;
+ Integer age;
+}
+
+@Embeddable
+class UserId implements Serializable {
+ String firstName;
+ String lastName;
+}</programlisting>
+
+ <para>Let's now rewrite these examples using the hbm.xml syntax.
+ </para>
+
+ <programlisting role="XML"><composite-id
+ name="propertyName"
+ class="ClassName"
+ mapped="true|false"
+ access="field|property|ClassName">
+ node="element-name|."
+
+ <key-property name="propertyName" type="typename" column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
+ ......
+</composite-id></programlisting>
+
+ <para>First a simple example:</para>
+
+ <programlisting role="XML"><class name="User">
+ <composite-id name="id" class="UserId">
+ <key-property name="firstName" column="fld_firstname"/>
+ <key-property name="lastName"/>
+ </composite-id>
+</class></programlisting>
+
+ <para>Then an example showing how an association can be
+ mapped.</para>
+
+ <programlisting role="XML"><class name="Customer">
+ <composite-id name="id" class="CustomerId">
+ <key-property name="firstName" column="userfirstname_fk"/>
+ <key-property name="lastName" column="userfirstname_fk"/>
+ <key-property name="customerNumber"/>
+ </composite-id>
+
+ <property name="preferredCustomer"/>
+
+ <many-to-one name="user">
+ <column name="userfirstname_fk" updatable="false" insertable="false"/>
+ <column name="userlastname_fk" updatable="false" insertable="false"/>
+ </many-to-one>
+</class>
+
+<class name="User">
+ <composite-id name="id" class="UserId">
+ <key-property name="firstName"/>
+ <key-property name="lastName"/>
+ </composite-id>
+
+ <property name="age"/>
+</class></programlisting>
+
+ <para>Notice a few things in the previous example:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the order of the properties (and column) matters. It must
+ be the same between the association and the primary key of the
+ associated entity</para>
+ </listitem>
+
+ <listitem>
+ <para>the many to one uses the same columns as the primary key
+ and thus must be marked as read only
+ (<literal>insertable</literal> and <literal>updatable</literal>
+ to false).</para>
+ </listitem>
+
+ <listitem>
+ <para>unlike with <classname>@MapsId</classname>, the id value
+ of the associated entity is not transparently copied, check the
+ <literal>foreign</literal> id generator for more
+ information.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The last example shows how to map association directly in the
+ embedded id component.</para>
+
+ <programlisting role="XML"><class name="Customer">
+ <composite-id name="id" class="CustomerId">
+ <key-many-to-one name="user">
+ <column name="userfirstname_fk"/>
+ <column name="userlastname_fk"/>
+ </key-many-to-one>
+ <key-property name="customerNumber"/>
+ </composite-id>
+
+ <property name="preferredCustomer"/>
+
+ <many-to-one name="user">
+ <column name="userfirstname_fk" updatable="false" insertable="false"/>
+ <column name="userlastname_fk" updatable="false" insertable="false"/>
+ </many-to-one>
+</class>
+
+<class name="User">
+ <composite-id name="id" class="UserId">
+ <key-property name="firstName"/>
+ <key-property name="lastName"/>
+ </composite-id>
+
+ <property name="age"/>
+</class></programlisting>
+ </section>
+
+ <section>
+ <title>Multiple @Id properties</title>
+
+ <para>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</para>
+
+ <para>Another, arguably more natural, approach is to place
+ <classname>@Id</classname> on multiple properties of my entity. This
+ approach is only supported by Hibernate but does not require an
+ extra embeddable component.</para>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+class Customer implements Serializable {
+ @Id @OneToOne
+ @JoinColumns({
+ @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
+ @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
+ })
+ User user;
+
+ @Id String customerNumber;
+
+ boolean preferredCustomer;
+}
+
+@Entity
+class User {
+ @EmbeddedId UserId id;
+ Integer age;
+}
+
+@Embeddable
+class UserId implements Serializable {
+ String firstName;
+ String lastName;
+}</programlisting>
+
+ <para>In this case <classname>Customer</classname> being it's own
+ identifier representation, it must implement
+ <classname>Serializable</classname>.</para>
+ </section>
+
+ <section>
+ <title>@IdClass</title>
+
+ <para><classname>@IdClass</classname> on an entity points to the
+ class (component) representing the identifier of the class. The
+ properties marked <classname>@Id</classname> on the entity must have
+ their corresponding property on the <classname>@IdClass</classname>.
+ The return type of search twin property must be either identical for
+ basic properties or must correspond to the identifier class of the
+ associated entity for an association.</para>
+
+ <warning>
+ <para>This approach is inherited from the EJB 2 days and we
+ recommend against its use. But, after all it's your application
+ and Hibernate supports it.</para>
+ </warning>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+class Customer {
+ @Id @OneToOne
+ @JoinColumns({
+ @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
+ @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
+ })
+ User user;
+
+ @Id String customerNumber;
+
+ boolean preferredCustomer;
+}
+
+class CustomerId implements Serializable {
+ UserId user;
+ String customerNumber;
+}
+
+@Entity
+class User {
+ @EmbeddedId UserId id;
+ Integer age;
+}
+
+@Embeddable
+class UserId implements Serializable {
+ String firstName;
+ String lastName;
+}</programlisting>
+
+ <para><classname>Customer</classname> and
+ <classname>CustomerId</classname> do have the same properties
+ <literal>customerNumber</literal> as well as
+ <literal>user</literal>.</para>
+
+ <para>While not JPA standard, Hibernate let's you declare the
+ vanilla associated property in the
+ <classname>@IdClass</classname>.</para>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+class Customer {
+ @Id @OneToOne
+ @JoinColumns({
+ @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
+ @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
+ })
+ User user;
+
+ @Id String customerNumber;
+
+ boolean preferredCustomer;
+}
+
+class CustomerId implements Serializable {
+ @OneToOne User user;
+ String customerNumber;
+}
+
+@Entity
+class User {
+ @EmbeddedId UserId id;
+ Integer age;
+}
+
+@Embeddable
+class UserId implements Serializable {
+ String firstName;
+ String lastName;
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Partial identifier generation</title>
+
+ <para>Hibernate supports the automatic generation of some of the
+ identifier properties. Simply use the
+ <classname>@GeneratedValue</classname> annotation on one or several
+ id properties.</para>
+
+ <warning>
+ <para>The Hibernate team has always felt such a construct as
+ fundamentally wrong. Try hard to fix your data model before using
+ this feature.</para>
+ </warning>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+public class CustomerInventory implements Serializable {
+ @Id
+ @TableGenerator(name = "inventory",
+ table = "U_SEQUENCES",
+ pkColumnName = "S_ID",
+ valueColumnName = "S_NEXTNUM",
+ pkColumnValue = "inventory",
+ allocationSize = 1000)
+ @GeneratedValue(strategy = GenerationType.TABLE, generator = "inventory")
+ Integer id;
+
+
+ @Id @ManyToOne(cascade = CascadeType.MERGE)
+ Customer customer;
+}
+
+@Entity
+public class Customer implements Serializable {
+ @Id
+ private int id;
+}</programlisting>
+
+ <para>You can also generate properties inside an
+ <classname>@EmbeddedId</classname> class.</para>
+ </section>
+ </section>
+
<section id="mapping-declaration-id-generator" revision="2">
<title>Generator</title>
14 years, 7 months
Hibernate SVN: r19295 - in core/trunk: entitymanager/src/test/java/org/hibernate/ejb/test/lock and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: smarlow(a)redhat.com
Date: 2010-04-26 13:49:26 -0400 (Mon, 26 Apr 2010)
New Revision: 19295
Modified:
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java
Log:
HHH-5032 upgrade from optimistic to optimistic force does not work
Modified: core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-04-26 16:21:26 UTC (rev 19294)
+++ core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-04-26 17:49:26 UTC (rev 19295)
@@ -3225,8 +3225,8 @@
readLoader :
createEntityLoader( LockMode.PESSIMISTIC_FORCE_INCREMENT )
);
- loaders.put( LockMode.OPTIMISTIC, readLoader );
- loaders.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, readLoader );
+ loaders.put( LockMode.OPTIMISTIC, createEntityLoader( LockMode.OPTIMISTIC) );
+ loaders.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, createEntityLoader(LockMode.OPTIMISTIC_FORCE_INCREMENT) );
loaders.put(
"merge",
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java 2010-04-26 16:21:26 UTC (rev 19294)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java 2010-04-26 17:49:26 UTC (rev 19295)
@@ -210,6 +210,28 @@
em.close();
}
+ public void testLockOptimisticForceIncrementDifferentEm() throws Exception {
+ Lock lock = new Lock();
+ lock.setName( "force" );
+ EntityManager em1 = createIsolatedEntityManager();
+ em1.getTransaction().begin();
+ em1.persist( lock );
+ em1.getTransaction().commit();
+ em1.close();
+
+ EntityManager em2 = createIsolatedEntityManager();
+ em2.getTransaction().begin();
+ lock = em2.find( Lock.class, lock.getId(), LockModeType.OPTIMISTIC );
+ assertEquals( "lock mode should be OPTIMISTIC ", LockModeType.OPTIMISTIC, em2.getLockMode(lock) );
+ em2.lock( lock, LockModeType.OPTIMISTIC_FORCE_INCREMENT );
+ assertEquals( "lock mode should be OPTIMISTIC_FORCE_INCREMENT ", LockModeType.OPTIMISTIC_FORCE_INCREMENT, em2.getLockMode(lock) );
+ em2.getTransaction().commit();
+ em2.getTransaction().begin();
+ em2.remove( lock );
+ em2.getTransaction().commit();
+ em2.close();
+ }
+
public void testContendedPessimisticLock() throws Exception {
EntityManager em = getOrCreateEntityManager();
14 years, 7 months
Hibernate SVN: r19294 - core/trunk/annotations/src/main/java/org/hibernate/annotations.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-26 12:21:26 -0400 (Mon, 26 Apr 2010)
New Revision: 19294
Modified:
core/trunk/annotations/src/main/java/org/hibernate/annotations/Entity.java
Log:
HHH-5162 Deprecate @Entity.mutable in favor of @Immutable
Modified: core/trunk/annotations/src/main/java/org/hibernate/annotations/Entity.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/annotations/Entity.java 2010-04-26 16:18:45 UTC (rev 19293)
+++ core/trunk/annotations/src/main/java/org/hibernate/annotations/Entity.java 2010-04-26 16:21:26 UTC (rev 19294)
@@ -36,7 +36,11 @@
@Target(TYPE)
@Retention(RUNTIME)
public @interface Entity {
- /** Is this entity mutable (read only) or not */
+ /**
+ * Is this entity mutable (read only) or not
+ *
+ * @deprecated use {@link org.hibernate.annotations.Immutable}
+ */
boolean mutable() default true;
/** Needed column only in SQL on insert */
boolean dynamicInsert() default false;
14 years, 7 months
Hibernate SVN: r19293 - in core/branches/Branch_3_5: entitymanager/src/test/java/org/hibernate/ejb/test/lock and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: smarlow(a)redhat.com
Date: 2010-04-26 12:18:45 -0400 (Mon, 26 Apr 2010)
New Revision: 19293
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
core/branches/Branch_3_5/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java
Log:
HHH-5032 upgrade from optimistic to optimistic force does not work
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-04-26 02:06:03 UTC (rev 19292)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-04-26 16:18:45 UTC (rev 19293)
@@ -3225,8 +3225,8 @@
readLoader :
createEntityLoader( LockMode.PESSIMISTIC_FORCE_INCREMENT )
);
- loaders.put( LockMode.OPTIMISTIC, readLoader );
- loaders.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, readLoader );
+ loaders.put( LockMode.OPTIMISTIC, createEntityLoader( LockMode.OPTIMISTIC) );
+ loaders.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, createEntityLoader(LockMode.OPTIMISTIC_FORCE_INCREMENT) );
loaders.put(
"merge",
Modified: core/branches/Branch_3_5/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java
===================================================================
--- core/branches/Branch_3_5/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java 2010-04-26 02:06:03 UTC (rev 19292)
+++ core/branches/Branch_3_5/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java 2010-04-26 16:18:45 UTC (rev 19293)
@@ -210,6 +210,28 @@
em.close();
}
+ public void testLockOptimisticForceIncrementDifferentEm() throws Exception {
+ Lock lock = new Lock();
+ lock.setName( "force" );
+ EntityManager em1 = createIsolatedEntityManager();
+ em1.getTransaction().begin();
+ em1.persist( lock );
+ em1.getTransaction().commit();
+ em1.close();
+
+ EntityManager em2 = createIsolatedEntityManager();
+ em2.getTransaction().begin();
+ lock = em2.find( Lock.class, lock.getId(), LockModeType.OPTIMISTIC );
+ assertEquals( "lock mode should be OPTIMISTIC ", LockModeType.OPTIMISTIC, em2.getLockMode(lock) );
+ em2.lock( lock, LockModeType.OPTIMISTIC_FORCE_INCREMENT );
+ assertEquals( "lock mode should be OPTIMISTIC_FORCE_INCREMENT ", LockModeType.OPTIMISTIC_FORCE_INCREMENT, em2.getLockMode(lock) );
+ em2.getTransaction().commit();
+ em2.getTransaction().begin();
+ em2.remove( lock );
+ em2.getTransaction().commit();
+ em2.close();
+ }
+
public void testContendedPessimisticLock() throws Exception {
EntityManager em = getOrCreateEntityManager();
14 years, 7 months