diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java index 617bfeaed7..90f1c35d20 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java @@ -26,6 +26,7 @@ package org.hibernate.dialect; import java.sql.Types; import org.hibernate.type.descriptor.sql.BlobTypeDescriptor; +import org.hibernate.type.descriptor.sql.ClobTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; @@ -48,7 +49,15 @@ public class SybaseDialect extends AbstractTransactSQLDialect { @Override protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) { - return sqlCode == Types.BLOB ? BlobTypeDescriptor.PRIMITIVE_ARRAY_BINDING : super.getSqlTypeDescriptorOverride( sqlCode ); + switch (sqlCode) { + case Types.BLOB: + return BlobTypeDescriptor.PRIMITIVE_ARRAY_BINDING; + case Types.CLOB: + // Some Sybase drivers cannot support getClob. See HHH-7889 + return ClobTypeDescriptor.STREAM_BINDING_EXTRACTING; + default: + return super.getSqlTypeDescriptorOverride( sqlCode ); + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java index 62b40f7b7c..dde15c23f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java @@ -105,11 +105,11 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor { try { if ( CharacterStream.class.isAssignableFrom( type ) ) { if ( ClobImplementer.class.isInstance( value ) ) { - // if the incoming Clob is a wrapper, just pass along its BinaryStream + // if the incoming Clob is a wrapper, just pass along its CharacterStream return (X) ( (ClobImplementer) value ).getUnderlyingStream(); } else { - // otherwise we need to build a BinaryStream... + // otherwise we need to build a CharacterStream... return (X) new CharacterStreamImpl( DataHelper.extractString( value.getCharacterStream() ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java index 88b50ee025..5df9cd61dd 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java @@ -30,6 +30,7 @@ import java.sql.SQLException; import java.sql.Types; import org.hibernate.engine.jdbc.BinaryStream; +import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; @@ -55,11 +56,14 @@ public abstract class BlobTypeDescriptor implements SqlTypeDescriptor { return true; } - protected abstract BasicExtractor getBlobExtractor(final JavaTypeDescriptor javaTypeDescriptor); - @Override - public BasicExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return getBlobExtractor( javaTypeDescriptor ); + public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) { + return new BasicExtractor( javaTypeDescriptor, this ) { + @Override + protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { + return javaTypeDescriptor.wrap( rs.getBlob( name ), options ); + } + }; } protected abstract BasicBinder getBlobBinder(final JavaTypeDescriptor javaTypeDescriptor); @@ -87,25 +91,7 @@ public abstract class BlobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getBlobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return getBinding( options ).getExtractor( javaTypeDescriptor ).doExtract( rs, name, options ); - } - }; - } }; - - private static final BlobTypeDescriptor getBinding( WrapperOptions options ) { - // TODO: STREAM_BINDING causes multiple tests to fail on oracle and - // mssql. The extracted blob is not the same size as what was persisted. - // For now, rely only on BLOB_BINDING. SEe HHH-8018. -// return options.useStreamForLobBinding() ? STREAM_BINDING : BLOB_BINDING; - return BLOB_BINDING; - } public static final BlobTypeDescriptor PRIMITIVE_ARRAY_BINDING = new BlobTypeDescriptor() { @@ -119,16 +105,6 @@ public abstract class BlobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getBlobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getBytes( name ), options ); - } - }; - } }; public static final BlobTypeDescriptor BLOB_BINDING = @@ -143,16 +119,6 @@ public abstract class BlobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getBlobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getBlob( name ), options ); - } - }; - } }; public static final BlobTypeDescriptor STREAM_BINDING = @@ -168,16 +134,6 @@ public abstract class BlobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getBlobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getBinaryStream( name ), options ); - } - }; - } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java index 7e48e23a52..84a949a3d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java @@ -23,7 +23,6 @@ */ package org.hibernate.type.descriptor.sql; -import java.sql.CallableStatement; import java.sql.Clob; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -52,13 +51,16 @@ public abstract class ClobTypeDescriptor implements SqlTypeDescriptor { public boolean canBeRemapped() { return true; } - - protected abstract BasicExtractor getClobExtractor(JavaTypeDescriptor javaTypeDescriptor); - - @Override - public ValueExtractor getExtractor(JavaTypeDescriptor javaTypeDescriptor) { - return getClobExtractor( javaTypeDescriptor ); - } + + @Override + public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) { + return new BasicExtractor( javaTypeDescriptor, this ) { + @Override + protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { + return javaTypeDescriptor.wrap( rs.getClob( name ), options ); + } + }; + } protected abstract BasicBinder getClobBinder(JavaTypeDescriptor javaTypeDescriptor); @@ -75,25 +77,16 @@ public abstract class ClobTypeDescriptor implements SqlTypeDescriptor { return new BasicBinder( javaTypeDescriptor, this ) { @Override protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException { - getBinding( options ).getClobBinder( javaTypeDescriptor ).doBind( st, value, index, options ); + if ( options.useStreamForLobBinding() ) { + STREAM_BINDING.getClobBinder( javaTypeDescriptor ).doBind( st, value, index, options ); + } + else { + CLOB_BINDING.getClobBinder( javaTypeDescriptor ).doBind( st, value, index, options ); + } } }; } - - @Override - public BasicExtractor getClobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return getBinding( options ).getClobExtractor( javaTypeDescriptor ).doExtract( rs, name, options ); - } - }; - } }; - - private static final ClobTypeDescriptor getBinding( WrapperOptions options ) { - return options.useStreamForLobBinding() ? STREAM_BINDING : CLOB_BINDING; - } public static final ClobTypeDescriptor CLOB_BINDING = new ClobTypeDescriptor() { @@ -107,18 +100,6 @@ public abstract class ClobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getClobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor(javaTypeDescriptor, this) { - - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getClob( name ), options ); - } - - }; - }; }; public static final ClobTypeDescriptor STREAM_BINDING = @@ -134,18 +115,31 @@ public abstract class ClobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getClobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor(javaTypeDescriptor, this) { + }; - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getCharacterStream( name ), options ); - } - - }; - }; + public static final ClobTypeDescriptor STREAM_BINDING_EXTRACTING = + new ClobTypeDescriptor() { + @Override + public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) { + return new BasicBinder( javaTypeDescriptor, this ) { + @Override + protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) + throws SQLException { + final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options ); + st.setCharacterStream( index, characterStream.asReader(), characterStream.getLength() ); + } + }; + } + + @Override + public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) { + return new BasicExtractor( javaTypeDescriptor, this ) { + @Override + protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { + return javaTypeDescriptor.wrap( rs.getCharacterStream( name ), options ); + } + }; + } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/NClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/NClobTypeDescriptor.java index 9edee44ab7..b030d4faa6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/NClobTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/NClobTypeDescriptor.java @@ -23,7 +23,6 @@ */ package org.hibernate.type.descriptor.sql; -import java.sql.CallableStatement; import java.sql.NClob; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -52,13 +51,16 @@ public abstract class NClobTypeDescriptor implements SqlTypeDescriptor { public boolean canBeRemapped() { return true; } - - protected abstract BasicExtractor getNClobExtractor(JavaTypeDescriptor javaTypeDescriptor); - - @Override - public ValueExtractor getExtractor(JavaTypeDescriptor javaTypeDescriptor) { - return getNClobExtractor( javaTypeDescriptor ); - } + + @Override + public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) { + return new BasicExtractor( javaTypeDescriptor, this ) { + @Override + protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { + return javaTypeDescriptor.wrap( rs.getNClob( name ), options ); + } + }; + } protected abstract BasicBinder getNClobBinder(JavaTypeDescriptor javaTypeDescriptor); @@ -75,25 +77,16 @@ public abstract class NClobTypeDescriptor implements SqlTypeDescriptor { return new BasicBinder( javaTypeDescriptor, this ) { @Override protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException { - getBinding( options ).getNClobBinder( javaTypeDescriptor ).doBind( st, value, index, options ); + if ( options.useStreamForLobBinding() ) { + STREAM_BINDING.getNClobBinder( javaTypeDescriptor ).doBind( st, value, index, options ); + } + else { + NCLOB_BINDING.getNClobBinder( javaTypeDescriptor ).doBind( st, value, index, options ); + } } }; } - - @Override - public BasicExtractor getNClobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return getBinding( options ).getNClobExtractor( javaTypeDescriptor ).doExtract( rs, name, options ); - } - }; - } }; - - private static final NClobTypeDescriptor getBinding( WrapperOptions options ) { - return options.useStreamForLobBinding() ? STREAM_BINDING : NCLOB_BINDING; - } public static final NClobTypeDescriptor NCLOB_BINDING = new NClobTypeDescriptor() { @@ -107,18 +100,6 @@ public abstract class NClobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getNClobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor(javaTypeDescriptor, this) { - - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getNClob( name ), options ); - } - - }; - }; }; public static final NClobTypeDescriptor STREAM_BINDING = @@ -134,17 +115,5 @@ public abstract class NClobTypeDescriptor implements SqlTypeDescriptor { } }; } - - @Override - public BasicExtractor getNClobExtractor(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor(javaTypeDescriptor, this) { - - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getCharacterStream( name ), options ); - } - - }; - }; }; }