diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryLiteralHelper.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryLiteralHelper.java new file mode 100644 index 0000000000..d52e8ad0f0 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryLiteralHelper.java @@ -0,0 +1,35 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.query.internal; + +/** + * @author Christian Beikov + */ +public class QueryLiteralHelper { + private QueryLiteralHelper() { + // disallow direct instantiation + } + + public static String toStringLiteral(String value) { + final StringBuilder sb = new StringBuilder( value.length() + 2 ); + appendStringLiteral( sb, value ); + return sb.toString(); + } + + public static void appendStringLiteral(StringBuilder sb, String value) { + sb.append( '\'' ); + for ( int i = 0; i < value.length(); i++ ) { + final char c = value.charAt( i ); + if ( c == '\'' ) { + sb.append( '\'' ); + } + sb.append( c ); + } + sb.append( '\'' ); + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java index 90bed8d07f..c0de760bbf 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.sqm.tree.expression; +import org.hibernate.query.internal.QueryLiteralHelper; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressable; @@ -54,15 +55,7 @@ public class SqmLiteral public static void appendHqlString(StringBuilder sb, JavaTypeDescriptor javaTypeDescriptor, T value) { final String string = javaTypeDescriptor.toString( value ); if ( javaTypeDescriptor.getJavaTypeClass() == String.class ) { - sb.append( '\'' ); - for ( int i = 0; i < string.length(); i++ ) { - final char c = string.charAt( i ); - if ( c == '\'' ) { - sb.append( '\'' ); - } - sb.append( c ); - } - sb.append( '\'' ); + QueryLiteralHelper.appendStringLiteral( sb, string ); } else { sb.append( string ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java index 95176cdaad..1e4a16f4d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java @@ -18,6 +18,7 @@ import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; +import org.hibernate.type.internal.NamedStandardBasicTypeImpl; import org.hibernate.type.internal.StandardBasicTypeImpl; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.UserType; @@ -75,6 +76,15 @@ public class BasicTypeRegistry implements Serializable { ); } + public BasicType resolve(JavaTypeDescriptor jtdToUse, JdbcTypeDescriptor stdToUse, String baseTypeName) { + //noinspection unchecked + return resolve( + jtdToUse, + stdToUse, + () -> new NamedStandardBasicTypeImpl<>( jtdToUse, stdToUse, baseTypeName ) + ); + } + /** * Find an existing BasicType registration for the given JavaTypeDescriptor and * SqlTypeDescriptor combo or create (and register) one. diff --git a/hibernate-core/src/main/java/org/hibernate/type/BinaryType.java b/hibernate-core/src/main/java/org/hibernate/type/BinaryType.java index d70abad6a4..34dd529d2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BinaryType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BinaryType.java @@ -100,6 +100,6 @@ public class BinaryType final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry(); final JdbcTypeDescriptor jdbcType = jdbcTypeRegistry.getDescriptor( Types.BLOB ); - return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType ); + return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType, getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/BooleanType.java b/hibernate-core/src/main/java/org/hibernate/type/BooleanType.java index c54e037a00..2a12ae24cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BooleanType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BooleanType.java @@ -88,7 +88,7 @@ public class BooleanType //noinspection unchecked return (BasicType) indicators.getTypeConfiguration() .getBasicTypeRegistry() - .resolve( getJavaTypeDescriptor(), jdbcTypeDescriptor ); + .resolve( getJavaTypeDescriptor(), jdbcTypeDescriptor, getName() ); } //noinspection unchecked diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharArrayType.java b/hibernate-core/src/main/java/org/hibernate/type/CharArrayType.java index 946e1da25c..5c645919e7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CharArrayType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CharArrayType.java @@ -57,6 +57,6 @@ public class CharArrayType } final JdbcTypeDescriptor jdbcType = jdbcTypeRegistry.getDescriptor( jdbcTypeCode ); - return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType ); + return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType, getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java index fa0ea0ec4b..4ba3712ca8 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java @@ -52,7 +52,8 @@ public class CharacterArrayClobType return typeConfiguration.getBasicTypeRegistry().resolve( typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( domainJtd.getJavaType() ), - jdbcType + jdbcType, + getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayNClobType.java b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayNClobType.java index e669f20a4b..c73b6beb38 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayNClobType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayNClobType.java @@ -50,7 +50,8 @@ public class CharacterArrayNClobType return typeConfiguration.getBasicTypeRegistry().resolve( typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( domainJtd.getJavaType() ), - jdbcType + jdbcType, + getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayType.java b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayType.java index b1e7863cf8..a524fc60fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayType.java @@ -59,7 +59,8 @@ public class CharacterArrayType if ( domainJtd != null && domainJtd.getJavaTypeClass() == Character[].class ) { return typeConfiguration.getBasicTypeRegistry().resolve( typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( domainJtd.getJavaType() ), - indicatedJdbcType + indicatedJdbcType, + getName() ); } @@ -69,7 +70,8 @@ public class CharacterArrayType return (BasicType) typeConfiguration.getBasicTypeRegistry().resolve( getJavaTypeDescriptor(), - indicatedJdbcType + indicatedJdbcType, + getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharacterNCharType.java b/hibernate-core/src/main/java/org/hibernate/type/CharacterNCharType.java index 6499de2154..c235fc01ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CharacterNCharType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CharacterNCharType.java @@ -41,7 +41,13 @@ public class CharacterNCharType } public String objectToSQLString(Character value, Dialect dialect) { - return '\'' + toString( value ) + '\''; + if ( value == '\'' ) { + return "''''"; + } + final char[] chars = new char[3]; + chars[0] = chars[2] = '\''; + chars[1] = value; + return new String( chars ); } public Character stringToObject(String xml) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharacterType.java b/hibernate-core/src/main/java/org/hibernate/type/CharacterType.java index 7085085d5c..6626829f6d 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CharacterType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CharacterType.java @@ -52,7 +52,13 @@ public class CharacterType } public String objectToSQLString(Character value, Dialect dialect) { - return '\'' + toString( value ) + '\''; + if ( value == '\'' ) { + return "''''"; + } + final char[] chars = new char[3]; + chars[0] = chars[2] = '\''; + chars[1] = value; + return new String( chars ); } public Character stringToObject(String xml) { @@ -69,6 +75,6 @@ public class CharacterType ? jdbcTypeRegistry.getDescriptor( Types.NCHAR ) : jdbcTypeRegistry.getDescriptor( Types.CHAR ); - return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType ); + return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType, getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/ClobType.java b/hibernate-core/src/main/java/org/hibernate/type/ClobType.java index cc8d3edb3e..6f1c809363 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ClobType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ClobType.java @@ -58,7 +58,8 @@ public class ClobType extends AbstractSingleColumnStandardBasicType implem return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, - jdbcTypeRegistry.getDescriptor( Types.NCLOB ) + jdbcTypeRegistry.getDescriptor( Types.NCLOB ), + getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java index 5b3d31a5d7..d8cd1bc237 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java @@ -168,6 +168,7 @@ public class EnumType> relationalJtd ); } + this.jdbcTypeDescriptor = jdbcTypeDescriptor; } else { final String enumClassName = (String) parameters.get( ENUM ); @@ -180,9 +181,9 @@ public class EnumType> this.enumValueConverter = interpretParameters( parameters ); this.jdbcTypeDescriptor = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( enumValueConverter.getJdbcTypeCode() ); - this.jdbcValueExtractor = (ValueExtractor) jdbcTypeDescriptor.getExtractor( enumValueConverter.getRelationalJavaDescriptor() ); - this.jdbcValueBinder = (ValueBinder) jdbcTypeDescriptor.getBinder( enumValueConverter.getRelationalJavaDescriptor() ); } + this.jdbcValueExtractor = (ValueExtractor) jdbcTypeDescriptor.getExtractor( enumValueConverter.getRelationalJavaDescriptor() ); + this.jdbcValueBinder = (ValueBinder) jdbcTypeDescriptor.getBinder( enumValueConverter.getRelationalJavaDescriptor() ); if ( LOG.isDebugEnabled() ) { LOG.debugf( diff --git a/hibernate-core/src/main/java/org/hibernate/type/InstantType.java b/hibernate-core/src/main/java/org/hibernate/type/InstantType.java index 5a82962dfd..a95efcbaeb 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/InstantType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/InstantType.java @@ -57,7 +57,7 @@ public class InstantType @Override public String getName() { - return Instant.class.getSimpleName(); + return "instant"; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java b/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java index b167d9f636..32a23604cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java @@ -46,7 +46,8 @@ public class MaterializedClobType return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, - nclobType + nclobType, + getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java b/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java index 948d9410c8..32c3b2826b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java @@ -47,7 +47,8 @@ public class PrimitiveCharacterArrayClobType return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, - jdbcTypeRegistry.getDescriptor( Types.NCLOB ) + jdbcTypeRegistry.getDescriptor( Types.NCLOB ), + getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/PrimitiveType.java b/hibernate-core/src/main/java/org/hibernate/type/PrimitiveType.java index 696ce02284..31c6f9cebf 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/PrimitiveType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/PrimitiveType.java @@ -44,6 +44,6 @@ public interface PrimitiveType extends LiteralType, AdjustableBasicType @Override default BasicType resolveIndicatedType(JdbcTypeDescriptorIndicators indicators, JavaTypeDescriptor domainJtd) { final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration(); - return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, getJdbcTypeDescriptor() ); + return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, getJdbcTypeDescriptor(), getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java b/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java index 5859b5f260..3f5a82a5c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java +++ b/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java @@ -29,11 +29,6 @@ import java.util.Locale; import java.util.TimeZone; import java.util.UUID; -import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor; -import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor; -import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor; -import org.hibernate.type.descriptor.jdbc.NClobTypeDescriptor; -import org.hibernate.type.internal.StandardBasicTypeImpl; import org.hibernate.type.spi.TypeConfiguration; /** @@ -243,11 +238,7 @@ public final class StandardBasicTypes { * @see #MATERIALIZED_CLOB * @see #TEXT */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public static final StandardBasicTypeImpl MATERIALIZED_CLOB_CHAR_ARRAY = new StandardBasicTypeImpl( - PrimitiveCharacterArrayTypeDescriptor.INSTANCE, - ClobTypeDescriptor.CLOB_BINDING - ); + public static final CharacterArrayClobType MATERIALIZED_CLOB_CHAR_ARRAY = PrimitiveCharacterArrayClobType.INSTANCE; /** @@ -256,11 +247,7 @@ public final class StandardBasicTypes { * @see #MATERIALIZED_CLOB * @see #TEXT */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public static final StandardBasicTypeImpl MATERIALIZED_CLOB_CHARACTER_ARRAY = new StandardBasicTypeImpl( - CharacterArrayTypeDescriptor.INSTANCE, - ClobTypeDescriptor.CLOB_BINDING - ); + public static final CharacterArrayClobType MATERIALIZED_CLOB_CHARACTER_ARRAY = CharacterArrayClobType.INSTANCE; /** @@ -269,11 +256,7 @@ public final class StandardBasicTypes { * @see #MATERIALIZED_NCLOB * @see #TEXT */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public static final StandardBasicTypeImpl MATERIALIZED_NCLOB_CHAR_ARRAY = new StandardBasicTypeImpl( - PrimitiveCharacterArrayTypeDescriptor.INSTANCE, - NClobTypeDescriptor.NCLOB_BINDING - ); + public static final CharacterArrayNClobType MATERIALIZED_NCLOB_CHAR_ARRAY = PrimitiveCharacterArrayNClobType.INSTANCE; /** @@ -282,11 +265,7 @@ public final class StandardBasicTypes { * @see #NCLOB * @see #CHAR_ARRAY */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public static final StandardBasicTypeImpl MATERIALIZED_NCLOB_CHARACTER_ARRAY = new StandardBasicTypeImpl( - CharacterArrayTypeDescriptor.INSTANCE, - NClobTypeDescriptor.NCLOB_BINDING - ); + public static final CharacterArrayNClobType MATERIALIZED_NCLOB_CHARACTER_ARRAY = CharacterArrayNClobType.INSTANCE; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Date / time data diff --git a/hibernate-core/src/main/java/org/hibernate/type/StringNVarcharType.java b/hibernate-core/src/main/java/org/hibernate/type/StringNVarcharType.java index e5560229ff..5856a701e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/StringNVarcharType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/StringNVarcharType.java @@ -7,6 +7,7 @@ package org.hibernate.type; import org.hibernate.dialect.Dialect; +import org.hibernate.query.internal.QueryLiteralHelper; import org.hibernate.type.descriptor.java.StringTypeDescriptor; import org.hibernate.type.descriptor.jdbc.NVarcharTypeDescriptor; @@ -36,7 +37,7 @@ public class StringNVarcharType } public String objectToSQLString(String value, Dialect dialect) throws Exception { - return '\'' + value + '\''; + return QueryLiteralHelper.toStringLiteral( value ); } public String stringToObject(String xml) throws Exception { diff --git a/hibernate-core/src/main/java/org/hibernate/type/StringType.java b/hibernate-core/src/main/java/org/hibernate/type/StringType.java index 7291788750..315081ed6e 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/StringType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/StringType.java @@ -8,6 +8,7 @@ package org.hibernate.type; import java.sql.Types; import org.hibernate.dialect.Dialect; +import org.hibernate.query.internal.QueryLiteralHelper; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.StringTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators; @@ -41,7 +42,7 @@ public class StringType } public String objectToSQLString(String value, Dialect dialect) throws Exception { - return '\'' + value + '\''; + return QueryLiteralHelper.toStringLiteral( value ); } public String stringToObject(String xml) throws Exception { @@ -78,7 +79,8 @@ public class StringType return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, - jdbcTypeRegistry.getDescriptor( jdbcTypeCode ) + jdbcTypeRegistry.getDescriptor( jdbcTypeCode ), + getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/WrapperBinaryType.java b/hibernate-core/src/main/java/org/hibernate/type/WrapperBinaryType.java index 49ef1d1c92..e542e46ff7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/WrapperBinaryType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/WrapperBinaryType.java @@ -48,6 +48,10 @@ public class WrapperBinaryType extends AbstractSingleColumnStandardBasicType extends StandardBasicTypeImpl { + + private final String name; + + public NamedStandardBasicTypeImpl(JavaTypeDescriptor jtd, JdbcTypeDescriptor std, String name) { + super( jtd, std ); + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public BasicType resolveIndicatedType( + JdbcTypeDescriptorIndicators indicators, + JavaTypeDescriptor domainJtd) { + final JdbcTypeDescriptor recommendedSqlType = getJavaTypeDescriptor().getRecommendedJdbcType( indicators ); + if ( recommendedSqlType == getJdbcTypeDescriptor() ) { + return this; + } + + return indicators.getTypeConfiguration() + .getBasicTypeRegistry() + .resolve( getJavaTypeDescriptor(), recommendedSqlType, getName() ); + } +}