HHH-18512 cleanup code surrounding custom PostgreSQL and Oracle types

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-08-23 13:14:23 +02:00
parent 54d80f6d1c
commit 1f9add32c2
12 changed files with 162 additions and 271 deletions

View File

@ -5207,6 +5207,13 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
Integer precision, Integer precision,
Integer scale, Integer scale,
Long length); Long length);
default Size resolveSize(
JdbcType jdbcType,
JavaType<?> javaType,
Size size) {
return resolveSize( jdbcType, javaType, size.getPrecision(), size.getScale(), size.getLength() );
}
} }
public class SizeStrategyImpl implements SizeStrategy { public class SizeStrategyImpl implements SizeStrategy {

View File

@ -14,8 +14,8 @@ import java.sql.Types;
import java.util.Locale; import java.util.Locale;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.engine.jdbc.Size; import org.hibernate.engine.jdbc.Size;
import org.hibernate.mapping.UserDefinedArrayType; import org.hibernate.mapping.UserDefinedArrayType;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
@ -31,14 +31,16 @@ import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.BasicExtractor; import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.descriptor.jdbc.SqlTypedJdbcType; import org.hibernate.type.descriptor.jdbc.SqlTypedJdbcType;
import org.hibernate.type.descriptor.jdbc.StructJdbcType; import org.hibernate.type.descriptor.jdbc.StructJdbcType;
import org.hibernate.type.internal.BasicTypeImpl; import org.hibernate.type.internal.BasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import oracle.jdbc.OracleConnection; import oracle.jdbc.OracleConnection;
import org.hibernate.type.spi.TypeConfiguration;
import static java.sql.Types.ARRAY; import static java.sql.Types.ARRAY;
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
/** /**
* Descriptor for {@link Types#ARRAY ARRAY} handling. * Descriptor for {@link Types#ARRAY ARRAY} handling.
@ -69,14 +71,16 @@ public class OracleArrayJdbcType extends ArrayJdbcType implements SqlTypedJdbcTy
@Override @Override
public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) { public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
//noinspection unchecked @SuppressWarnings("unchecked")
final ValueBinder<Object> elementBinder = getElementJdbcType().getBinder( ( (BasicPluralJavaType<Object>) javaTypeDescriptor ).getElementJavaType() ); final BasicPluralJavaType<X> pluralJavaType = (BasicPluralJavaType<X>) javaTypeDescriptor;
final ValueBinder<X> elementBinder = getElementJdbcType().getBinder( pluralJavaType.getElementJavaType() );
return new BasicBinder<>( javaTypeDescriptor, this ) { return new BasicBinder<>( javaTypeDescriptor, this ) {
private String typeName(WrapperOptions options) { private String typeName(WrapperOptions options) {
return ( upperTypeName == null final BasicPluralJavaType<?> javaType = (BasicPluralJavaType<?>) getJavaType();
? getTypeName( options, (BasicPluralJavaType<?>) getJavaType(), (ArrayJdbcType) getJdbcType() ).toUpperCase( Locale.ROOT ) final ArrayJdbcType jdbcType = (ArrayJdbcType) getJdbcType();
: upperTypeName return upperTypeName == null
); ? getTypeName( options, javaType, jdbcType ).toUpperCase( Locale.ROOT )
: upperTypeName;
} }
@Override @Override
protected void doBindNull(PreparedStatement st, int index, WrapperOptions options) throws SQLException { protected void doBindNull(PreparedStatement st, int index, WrapperOptions options) throws SQLException {
@ -107,12 +111,12 @@ public class OracleArrayJdbcType extends ArrayJdbcType implements SqlTypedJdbcTy
@Override @Override
public java.sql.Array getBindValue(X value, WrapperOptions options) throws SQLException { public java.sql.Array getBindValue(X value, WrapperOptions options) throws SQLException {
final Object[] objects = ( (OracleArrayJdbcType) getJdbcType() ).getArray( this, elementBinder, value, options ); final OracleArrayJdbcType oracleArrayJdbcType = (OracleArrayJdbcType) getJdbcType();
final Object[] objects = oracleArrayJdbcType.getArray( this, elementBinder, value, options );
final String arrayTypeName = typeName( options ); final String arrayTypeName = typeName( options );
final OracleConnection oracleConnection =
final OracleConnection oracleConnection = options.getSession() options.getSession().getJdbcCoordinator().getLogicalConnection().getPhysicalConnection()
.getJdbcCoordinator().getLogicalConnection().getPhysicalConnection() .unwrap( OracleConnection.class );
.unwrap( OracleConnection.class );
try { try {
return oracleConnection.createOracleArray( arrayTypeName, objects ); return oracleConnection.createOracleArray( arrayTypeName, objects );
} }
@ -145,74 +149,81 @@ public class OracleArrayJdbcType extends ArrayJdbcType implements SqlTypedJdbcTy
} }
static String getTypeName(WrapperOptions options, BasicPluralJavaType<?> containerJavaType, ArrayJdbcType arrayJdbcType) { static String getTypeName(WrapperOptions options, BasicPluralJavaType<?> containerJavaType, ArrayJdbcType arrayJdbcType) {
Dialect dialect = options.getSessionFactory().getJdbcServices().getDialect(); final Dialect dialect = options.getSessionFactory().getJdbcServices().getDialect();
return getTypeName( containerJavaType.getElementJavaType(), arrayJdbcType.getElementJdbcType(), dialect ); return getTypeName( containerJavaType.getElementJavaType(), arrayJdbcType.getElementJdbcType(), dialect );
} }
static String getTypeName(BasicType<?> elementType, Dialect dialect) { static String getTypeName(BasicType<?> elementType, Dialect dialect) {
final BasicValueConverter<?, ?> converter = elementType.getValueConverter(); final BasicValueConverter<?, ?> converter = elementType.getValueConverter();
if ( converter != null ) { if ( converter != null ) {
final String simpleName;
if ( converter instanceof JpaAttributeConverter<?, ?> ) {
simpleName = ( (JpaAttributeConverter<?, ?>) converter ).getConverterJavaType()
.getJavaTypeClass()
.getSimpleName();
}
else {
simpleName = converter.getClass().getSimpleName();
}
return dialect.getArrayTypeName( return dialect.getArrayTypeName(
simpleName, converterClassName( converter ),
null, // not needed by OracleDialect.getArrayTypeName() null, // not needed by OracleDialect.getArrayTypeName()
null // not needed by OracleDialect.getArrayTypeName() null // not needed by OracleDialect.getArrayTypeName()
); );
} }
return getTypeName( elementType.getJavaTypeDescriptor(), elementType.getJdbcType(), dialect ); else {
return getTypeName( elementType.getJavaTypeDescriptor(), elementType.getJdbcType(), dialect );
}
}
private static String converterClassName(BasicValueConverter<?, ?> converter) {
if ( converter instanceof JpaAttributeConverter<?, ?> ) {
final JpaAttributeConverter<?, ?> jpaConverter = (JpaAttributeConverter<?, ?>) converter;
return jpaConverter.getConverterJavaType().getJavaTypeClass().getSimpleName();
}
else {
return converter.getClass().getSimpleName();
}
} }
static String getTypeName(JavaType<?> elementJavaType, JdbcType elementJdbcType, Dialect dialect) { static String getTypeName(JavaType<?> elementJavaType, JdbcType elementJdbcType, Dialect dialect) {
final String simpleName; return dialect.getArrayTypeName(
if ( elementJavaType.getJavaTypeClass().isArray() ) { arrayClassName( elementJavaType, elementJdbcType, dialect ),
simpleName = dialect.getArrayTypeName( null, // not needed by OracleDialect.getArrayTypeName()
elementJavaType.getJavaTypeClass().getComponentType().getSimpleName(), null // not needed by OracleDialect.getArrayTypeName()
);
}
private static String arrayClassName(JavaType<?> elementJavaType, JdbcType elementJdbcType, Dialect dialect) {
final Class<?> javaClass = elementJavaType.getJavaTypeClass();
if ( javaClass.isArray() ) {
return dialect.getArrayTypeName(
javaClass.getComponentType().getSimpleName(),
null, // not needed by OracleDialect.getArrayTypeName() null, // not needed by OracleDialect.getArrayTypeName()
null // not needed by OracleDialect.getArrayTypeName() null // not needed by OracleDialect.getArrayTypeName()
); );
} }
else if ( elementJdbcType instanceof StructJdbcType ) { else if ( elementJdbcType instanceof StructJdbcType ) {
simpleName = ( (StructJdbcType) elementJdbcType ).getStructTypeName(); return ( (StructJdbcType) elementJdbcType).getStructTypeName();
} }
else { else {
final Class<?> preferredJavaTypeClass = elementJdbcType.getPreferredJavaTypeClass( null ); final Class<?> preferredJavaTypeClass = elementJdbcType.getPreferredJavaTypeClass( null );
if ( preferredJavaTypeClass == elementJavaType.getJavaTypeClass() ) { if ( preferredJavaTypeClass == javaClass) {
simpleName = elementJavaType.getJavaTypeClass().getSimpleName(); return javaClass.getSimpleName();
} }
else { else {
if ( preferredJavaTypeClass.isArray() ) { if ( preferredJavaTypeClass.isArray() ) {
simpleName = elementJavaType.getJavaTypeClass().getSimpleName() + dialect.getArrayTypeName( return javaClass.getSimpleName() + dialect.getArrayTypeName(
preferredJavaTypeClass.getComponentType().getSimpleName(), preferredJavaTypeClass.getComponentType().getSimpleName(),
null, null,
null null
); );
} }
else { else {
simpleName = elementJavaType.getJavaTypeClass().getSimpleName() + preferredJavaTypeClass.getSimpleName(); return javaClass.getSimpleName() + preferredJavaTypeClass.getSimpleName();
} }
} }
} }
return dialect.getArrayTypeName(
simpleName,
null, // not needed by OracleDialect.getArrayTypeName()
null // not needed by OracleDialect.getArrayTypeName()
);
} }
@Override @Override
public void addAuxiliaryDatabaseObjects( public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType, JavaType<?> javaType,
BasicValueConverter<?, ?> valueConverter,
Size columnSize, Size columnSize,
Database database, Database database,
TypeConfiguration typeConfiguration) { JdbcTypeIndicators context) {
final JdbcType elementJdbcType = getElementJdbcType(); final JdbcType elementJdbcType = getElementJdbcType();
if ( elementJdbcType instanceof StructJdbcType ) { if ( elementJdbcType instanceof StructJdbcType ) {
// OracleAggregateSupport will take care of contributing the auxiliary database object // OracleAggregateSupport will take care of contributing the auxiliary database object
@ -221,28 +232,41 @@ public class OracleArrayJdbcType extends ArrayJdbcType implements SqlTypedJdbcTy
final Dialect dialect = database.getDialect(); final Dialect dialect = database.getDialect();
final BasicPluralJavaType<?> pluralJavaType = (BasicPluralJavaType<?>) javaType; final BasicPluralJavaType<?> pluralJavaType = (BasicPluralJavaType<?>) javaType;
final JavaType<?> elementJavaType = pluralJavaType.getElementJavaType(); final JavaType<?> elementJavaType = pluralJavaType.getElementJavaType();
final String arrayTypeName = typeName == null ? getTypeName( elementJavaType, elementJdbcType, dialect ) : typeName; final String elementTypeName =
final String elementType = typeConfiguration.getDdlTypeRegistry().getTypeName( elementType( elementJavaType, elementJdbcType, columnSize, context.getTypeConfiguration(), dialect );
elementJdbcType.getDdlTypeCode(), final String arrayTypeName = arrayTypeName( elementJavaType, elementJdbcType, dialect );
dialect.getSizeStrategy().resolveSize( createUserDefinedArrayType( arrayTypeName, elementTypeName, columnSize, elementJdbcType, database );
elementJdbcType, }
elementJavaType,
columnSize.getPrecision(), private String arrayTypeName(JavaType<?> elementJavaType, JdbcType elementJdbcType, Dialect dialect) {
columnSize.getScale(), return typeName == null
columnSize.getLength() ? getTypeName( elementJavaType, elementJdbcType, dialect )
), : typeName;
new BasicTypeImpl<>( elementJavaType, elementJdbcType ) }
);
final UserDefinedArrayType userDefinedArrayType = database.getDefaultNamespace().createUserDefinedArrayType( private void createUserDefinedArrayType(
Identifier.toIdentifier( arrayTypeName ), String arrayTypeName, String elementTypeName, Size columnSize, JdbcType elementJdbcType, Database database) {
name -> new UserDefinedArrayType( "orm", database.getDefaultNamespace(), name ) final Namespace defaultNamespace = database.getDefaultNamespace();
); final UserDefinedArrayType userDefinedArrayType =
defaultNamespace.createUserDefinedArrayType(
toIdentifier( arrayTypeName ),
name -> new UserDefinedArrayType( "orm", defaultNamespace, name )
);
userDefinedArrayType.setArraySqlTypeCode( getDdlTypeCode() ); userDefinedArrayType.setArraySqlTypeCode( getDdlTypeCode() );
userDefinedArrayType.setElementTypeName( elementType ); userDefinedArrayType.setElementTypeName( elementTypeName );
userDefinedArrayType.setElementSqlTypeCode( elementJdbcType.getDefaultSqlTypeCode() ); userDefinedArrayType.setElementSqlTypeCode( elementJdbcType.getDefaultSqlTypeCode() );
userDefinedArrayType.setArrayLength( columnSize.getArrayLength() == null ? 127 : columnSize.getArrayLength() ); userDefinedArrayType.setArrayLength( columnSize.getArrayLength() == null ? 127 : columnSize.getArrayLength() );
} }
private static String elementType(
JavaType<?> elementJavaType, JdbcType elementJdbcType, Size columnSize,
TypeConfiguration typeConfiguration, Dialect dialect) {
return typeConfiguration.getDdlTypeRegistry()
.getTypeName( elementJdbcType.getDdlTypeCode(),
dialect.getSizeStrategy().resolveSize( elementJdbcType, elementJavaType, columnSize ),
new BasicTypeImpl<>(elementJavaType, elementJdbcType) );
}
@Override @Override
public void registerOutParameter(CallableStatement callableStatement, String name) throws SQLException { public void registerOutParameter(CallableStatement callableStatement, String name) throws SQLException {
callableStatement.registerOutParameter( name, ARRAY, upperTypeName ); callableStatement.registerOutParameter( name, ARRAY, upperTypeName );
@ -255,12 +279,9 @@ public class OracleArrayJdbcType extends ArrayJdbcType implements SqlTypedJdbcTy
@Override @Override
public String getExtraCreateTableInfo(JavaType<?> javaType, String columnName, String tableName, Database database) { public String getExtraCreateTableInfo(JavaType<?> javaType, String columnName, String tableName, Database database) {
return getElementJdbcType().getExtraCreateTableInfo( final BasicPluralJavaType<?> pluralJavaType = (BasicPluralJavaType<?>) javaType;
( (BasicPluralJavaType<?>) javaType ).getElementJavaType(), return getElementJdbcType()
columnName, .getExtraCreateTableInfo( pluralJavaType.getElementJavaType(), columnName, tableName, database );
tableName,
database
);
} }
@Override @Override

View File

@ -1683,6 +1683,27 @@ public class OracleDialect extends Dialect {
return new String[] { domain.toString() }; return new String[] { domain.toString() };
} }
/**
* Used to generate the {@code CREATE} DDL command for
* Data Use Case Domain based on {@code VARCHAR2} values.
*
* @return the DDL command to create that enum
*/
public static String[] getCreateVarcharEnumTypeCommand(String name, String[] values) {
final StringBuilder domain = new StringBuilder();
domain.append( "create domain " )
.append( name )
.append( " as enum (" );
String separator = "";
for ( String value : values ) {
domain.append( separator ).append( value ).append("='").append(value).append("'");
separator = ", ";
}
domain.append( ')' );
return new String[] { domain.toString() };
}
@Override @Override
public String[] getDropEnumTypeCommand(String name) { public String[] getDropEnumTypeCommand(String name) {
return new String[] { "drop domain if exists " + name + " force" }; return new String[] { "drop domain if exists " + name + " force" };

View File

@ -19,7 +19,6 @@ import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -64,7 +63,11 @@ public class OracleEnumJdbcType implements JdbcType {
@Override @Override
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) { public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
return (appender, value, dialect, wrapperOptions) -> appender.appendSql( dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) javaType.getJavaType() )+"." + ((Enum<?>) value).name() ); @SuppressWarnings("unchecked")
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
return (appender, value, dialect, wrapperOptions)
-> appender.appendSql( dialect.getEnumTypeDeclaration( enumClass )
+ "." + ((Enum<?>) value).name() );
} }
@Override @Override
@ -131,44 +134,24 @@ public class OracleEnumJdbcType implements JdbcType {
Size columnSize, Size columnSize,
Database database, Database database,
JdbcTypeIndicators context) { JdbcTypeIndicators context) {
addAuxiliaryDatabaseObjects( javaType, valueConverter, database, true );
}
@Override
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
addAuxiliaryDatabaseObjects( javaType, null, database, true );
}
private void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
BasicValueConverter<?, ?> valueConverter,
Database database,
boolean sortEnumValues) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType(); final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
final String enumTypeName = enumClass.getSimpleName();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final String[] enumeratedValues = final String[] enumeratedValues =
valueConverter == null valueConverter == null
? getEnumeratedValues( enumClass ) ? getEnumeratedValues( enumClass )
: getEnumeratedValues( enumClass, (BasicValueConverter<Enum<?>,?>) valueConverter ) ; : getEnumeratedValues( enumClass, (BasicValueConverter<Enum<?>,?>) valueConverter ) ;
if ( sortEnumValues ) { if ( getDefaultSqlTypeCode() == NAMED_ENUM ) {
Arrays.sort( enumeratedValues ); Arrays.sort( enumeratedValues );
} }
final Dialect dialect = database.getDialect(); final Dialect dialect = database.getDialect();
final String[] create = getCreateEnumTypeCommand( final String[] create =
javaType.getJavaTypeClass().getSimpleName(), getCreateEnumTypeCommand( javaType.getJavaTypeClass().getSimpleName(), enumeratedValues, dialect );
enumeratedValues
);
final String[] drop = dialect.getDropEnumTypeCommand( enumClass ); final String[] drop = dialect.getDropEnumTypeCommand( enumClass );
if ( create != null && create.length > 0 ) { if ( create != null && create.length > 0 ) {
database.addAuxiliaryDatabaseObject( database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject( new NamedAuxiliaryDatabaseObject(
enumTypeName, enumClass.getSimpleName(),
database.getDefaultNamespace(), database.getDefaultNamespace(),
create, create,
drop, drop,
@ -179,24 +162,7 @@ public class OracleEnumJdbcType implements JdbcType {
} }
} }
/** String[] getCreateEnumTypeCommand(String name, String[] values, Dialect dialect) {
* Used to generate the CREATE DDL command for Data Use Case Domain based on VARCHAR2 values. return OracleDialect.getCreateVarcharEnumTypeCommand( name, values );
*
* @param name
* @param values
* @return the DDL command to create that enum
*/
public String[] getCreateEnumTypeCommand(String name, String[] values) {
final StringBuilder domain = new StringBuilder();
domain.append( "create domain " )
.append( name )
.append( " as enum (" );
String separator = "";
for ( String value : values ) {
domain.append( separator ).append( value ).append("='").append(value).append("'");
separator = ", ";
}
domain.append( ')' );
return new String[] { domain.toString() };
} }
} }

View File

@ -13,13 +13,11 @@ import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.converter.internal.EnumHelper;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.BasicBinder; import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.BasicExtractor; import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -30,6 +28,7 @@ import java.util.Arrays;
import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
import static org.hibernate.type.SqlTypes.NAMED_ORDINAL_ENUM; import static org.hibernate.type.SqlTypes.NAMED_ORDINAL_ENUM;
import static org.hibernate.type.descriptor.converter.internal.EnumHelper.getEnumeratedValues;
/** /**
* Represents a named {@code enum} type on Oracle 23ai+. * Represents a named {@code enum} type on Oracle 23ai+.
@ -94,12 +93,9 @@ public class OracleOrdinalEnumJdbcType extends OracleEnumJdbcType {
@Override @Override
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException { protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
final int value = rs.getInt( paramIndex ); final int value = rs.getInt( paramIndex );
if(rs.wasNull()) { return rs.wasNull()
return getJavaType().wrap(null, options); ? getJavaType().wrap(null, options)
} : getJavaType().wrap(value - 1, options);
else {
return getJavaType().wrap(value - 1, options);
}
} }
@Override @Override
@ -115,51 +111,8 @@ public class OracleOrdinalEnumJdbcType extends OracleEnumJdbcType {
} }
@Override @Override
public void addAuxiliaryDatabaseObjects( String[] getCreateEnumTypeCommand(String name, String[] enumeratedValues, Dialect dialect) {
JavaType<?> javaType, return dialect.getCreateEnumTypeCommand( name, enumeratedValues );
BasicValueConverter<?, ?> valueConverter,
Size columnSize,
Database database,
JdbcTypeIndicators context) {
addAuxiliaryDatabaseObjects( javaType, database, false );
} }
@Override
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
addAuxiliaryDatabaseObjects( javaType, database, false );
}
private void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Database database,
boolean sortEnumValues) {
final Dialect dialect = database.getDialect();
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
final String enumTypeName = enumClass.getSimpleName();
final String[] enumeratedValues = EnumHelper.getEnumeratedValues( enumClass );
if ( sortEnumValues ) {
Arrays.sort( enumeratedValues );
}
final String[] create = dialect.getCreateEnumTypeCommand(
javaType.getJavaTypeClass().getSimpleName(),
enumeratedValues
);
final String[] drop = dialect.getDropEnumTypeCommand( enumClass );
if ( create != null && create.length > 0 ) {
database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject(
enumTypeName,
database.getDefaultNamespace(),
create,
drop,
emptySet(),
true
)
);
}
}
} }

View File

@ -33,8 +33,9 @@ public class PostgreSQLArrayJdbcType extends ArrayJdbcType {
@Override @Override
public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) { public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
//noinspection unchecked @SuppressWarnings("unchecked")
final ValueBinder<Object> elementBinder = getElementJdbcType().getBinder( ( (BasicPluralJavaType<Object>) javaTypeDescriptor ).getElementJavaType() ); final BasicPluralJavaType<X> pluralJavaType = (BasicPluralJavaType<X>) javaTypeDescriptor;
final ValueBinder<X> elementBinder = getElementJdbcType().getBinder( pluralJavaType.getElementJavaType() );
return new BasicBinder<>( javaTypeDescriptor, this ) { return new BasicBinder<>( javaTypeDescriptor, this ) {
@Override @Override

View File

@ -19,7 +19,6 @@ import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -65,9 +64,11 @@ public class PostgreSQLEnumJdbcType implements JdbcType {
@Override @Override
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) { public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
@SuppressWarnings("unchecked")
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
return (appender, value, dialect, wrapperOptions) return (appender, value, dialect, wrapperOptions)
-> appender.appendSql( "'" + ((Enum<?>) value).name() + "'::" -> appender.appendSql( "'" + ((Enum<?>) value).name() + "'::"
+ dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) javaType.getJavaType() ) ); + dialect.getEnumTypeDeclaration( enumClass ) );
} }
@Override @Override
@ -134,44 +135,24 @@ public class PostgreSQLEnumJdbcType implements JdbcType {
Size columnSize, Size columnSize,
Database database, Database database,
JdbcTypeIndicators context) { JdbcTypeIndicators context) {
addAuxiliaryDatabaseObjects( javaType, valueConverter, database, true );
}
@Override
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
addAuxiliaryDatabaseObjects( javaType, null, database, true );
}
protected void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
BasicValueConverter<?, ?> valueConverter,
Database database,
boolean sortEnumValues) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType(); final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
final String enumTypeName = enumClass.getSimpleName();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final String[] enumeratedValues = final String[] enumeratedValues =
valueConverter == null valueConverter == null
? getEnumeratedValues( enumClass ) ? getEnumeratedValues( enumClass )
: getEnumeratedValues( enumClass, (BasicValueConverter<Enum<?>,?>) valueConverter ) ; : getEnumeratedValues( enumClass, (BasicValueConverter<Enum<?>,?>) valueConverter ) ;
if ( sortEnumValues ) { if ( getDefaultSqlTypeCode() == NAMED_ENUM ) {
Arrays.sort( enumeratedValues ); Arrays.sort( enumeratedValues );
} }
final Dialect dialect = database.getDialect(); final Dialect dialect = database.getDialect();
final String[] create = dialect.getCreateEnumTypeCommand( final String[] create =
javaType.getJavaTypeClass().getSimpleName(), dialect.getCreateEnumTypeCommand( javaType.getJavaTypeClass().getSimpleName(), enumeratedValues );
enumeratedValues
);
final String[] drop = dialect.getDropEnumTypeCommand( enumClass ); final String[] drop = dialect.getDropEnumTypeCommand( enumClass );
if ( create != null && create.length > 0 ) { if ( create != null && create.length > 0 ) {
database.addAuxiliaryDatabaseObject( database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject( new NamedAuxiliaryDatabaseObject(
enumTypeName, enumClass.getSimpleName(),
database.getDefaultNamespace(), database.getDefaultNamespace(),
create, create,
drop, drop,

View File

@ -6,13 +6,6 @@
*/ */
package org.hibernate.dialect; package org.hibernate.dialect;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.EnumType; import jakarta.persistence.EnumType;
import static org.hibernate.type.SqlTypes.NAMED_ORDINAL_ENUM; import static org.hibernate.type.SqlTypes.NAMED_ORDINAL_ENUM;
@ -39,22 +32,4 @@ public class PostgreSQLOrdinalEnumJdbcType extends PostgreSQLEnumJdbcType {
public int getDefaultSqlTypeCode() { public int getDefaultSqlTypeCode() {
return NAMED_ORDINAL_ENUM; return NAMED_ORDINAL_ENUM;
} }
@Override
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
BasicValueConverter<?, ?> valueConverter, Size columnSize,
Database database,
JdbcTypeIndicators context) {
addAuxiliaryDatabaseObjects( javaType, valueConverter, database, false );
}
@Override
public void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
addAuxiliaryDatabaseObjects( javaType, null, database, false );
}
} }

View File

@ -141,20 +141,13 @@ public class ArrayJdbcType implements JdbcType {
} }
} }
protected Object[] getArray( protected <T> Object[] getArray(BasicBinder<?> binder, ValueBinder<T> elementBinder, T value, WrapperOptions options)
BasicBinder<?> binder, throws SQLException {
ValueBinder<Object> elementBinder,
Object value,
WrapperOptions options) throws SQLException {
final JdbcType elementJdbcType = ( (ArrayJdbcType) binder.getJdbcType() ).getElementJdbcType(); final JdbcType elementJdbcType = ( (ArrayJdbcType) binder.getJdbcType() ).getElementJdbcType();
//noinspection unchecked //noinspection unchecked
final JavaType<Object> javaType = (JavaType<Object>) binder.getJavaType(); final JavaType<T> javaType = (JavaType<T>) binder.getJavaType();
if ( elementJdbcType instanceof AggregateJdbcType ) { if ( elementJdbcType instanceof AggregateJdbcType ) {
final Object[] domainObjects = javaType.unwrap( final T[] domainObjects = (T[]) javaType.unwrap( value, Object[].class, options );
value,
Object[].class,
options
);
final Object[] objects = new Object[domainObjects.length]; final Object[] objects = new Object[domainObjects.length];
for ( int i = 0; i < domainObjects.length; i++ ) { for ( int i = 0; i < domainObjects.length; i++ ) {
objects[i] = elementBinder.getBindValue( domainObjects[i], options ); objects[i] = elementBinder.getBindValue( domainObjects[i], options );
@ -163,22 +156,15 @@ public class ArrayJdbcType implements JdbcType {
} }
else { else {
final TypeConfiguration typeConfiguration = options.getSessionFactory().getTypeConfiguration(); final TypeConfiguration typeConfiguration = options.getSessionFactory().getTypeConfiguration();
final JdbcType underlyingJdbcType = typeConfiguration.getJdbcTypeRegistry() final JdbcType underlyingJdbcType =
.getDescriptor( elementJdbcType.getDefaultSqlTypeCode() ); typeConfiguration.getJdbcTypeRegistry().getDescriptor( elementJdbcType.getDefaultSqlTypeCode() );
final Class<?> preferredJavaTypeClass = elementJdbcType.getPreferredJavaTypeClass( options ); final Class<?> preferredJavaTypeClass = elementJdbcType.getPreferredJavaTypeClass( options );
final Class<?> elementJdbcJavaTypeClass; final Class<?> elementJdbcJavaTypeClass =
if ( preferredJavaTypeClass == null ) { preferredJavaTypeClass == null
elementJdbcJavaTypeClass = underlyingJdbcType.getJdbcRecommendedJavaTypeMapping( ? underlyingJdbcType.getJdbcRecommendedJavaTypeMapping(null, null, typeConfiguration )
null, .getJavaTypeClass()
null, : preferredJavaTypeClass;
typeConfiguration final Class<? extends Object[]> arrayClass = (Class<? extends Object[]>)
).getJavaTypeClass();
}
else {
elementJdbcJavaTypeClass = preferredJavaTypeClass;
}
//noinspection unchecked
final Class<Object[]> arrayClass = (Class<Object[]>)
Array.newInstance( elementJdbcJavaTypeClass, 0 ).getClass(); Array.newInstance( elementJdbcJavaTypeClass, 0 ).getClass();
return javaType.unwrap( value, arrayClass, options ); return javaType.unwrap( value, arrayClass, options );
} }
@ -192,11 +178,8 @@ public class ArrayJdbcType implements JdbcType {
final Object[] domainObjects = new Object[Array.getLength( rawArray )]; final Object[] domainObjects = new Object[Array.getLength( rawArray )];
for ( int i = 0; i < domainObjects.length; i++ ) { for ( int i = 0; i < domainObjects.length; i++ ) {
final Object[] aggregateRawValues = aggregateJdbcType.extractJdbcValues( Array.get( rawArray, i ), options ); final Object[] aggregateRawValues = aggregateJdbcType.extractJdbcValues( Array.get( rawArray, i ), options );
final StructAttributeValues attributeValues = StructHelper.getAttributeValues( final StructAttributeValues attributeValues =
embeddableMappingType, StructHelper.getAttributeValues( embeddableMappingType, aggregateRawValues, options );
aggregateRawValues,
options
);
domainObjects[i] = instantiate( embeddableMappingType, attributeValues, options.getSessionFactory() ); domainObjects[i] = instantiate( embeddableMappingType, attributeValues, options.getSessionFactory() );
} }
return extractor.getJavaType().wrap( domainObjects, options ); return extractor.getJavaType().wrap( domainObjects, options );
@ -208,8 +191,9 @@ public class ArrayJdbcType implements JdbcType {
@Override @Override
public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) { public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
//noinspection unchecked @SuppressWarnings("unchecked")
final ValueBinder<Object> elementBinder = elementJdbcType.getBinder( ( (BasicPluralJavaType<Object>) javaTypeDescriptor ).getElementJavaType() ); final BasicPluralJavaType<X> pluralJavaType = (BasicPluralJavaType<X>) javaTypeDescriptor;
final ValueBinder<X> elementBinder = elementJdbcType.getBinder( pluralJavaType.getElementJavaType() );
return new BasicBinder<>( javaTypeDescriptor, this ) { return new BasicBinder<>( javaTypeDescriptor, this ) {
@Override @Override
@ -284,9 +268,9 @@ public class ArrayJdbcType implements JdbcType {
*/ */
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return o != null && return o != null
getClass() == o.getClass() && && getClass() == o.getClass()
getElementJdbcType().equals( ( (ArrayJdbcType) o ).getElementJdbcType() ); && getElementJdbcType().equals( ( (ArrayJdbcType) o ).getElementJdbcType() );
} }
@Override @Override

View File

@ -372,18 +372,6 @@ public interface JdbcType extends Serializable {
callableStatement.registerOutParameter( index, getJdbcTypeCode() ); callableStatement.registerOutParameter( index, getJdbcTypeCode() );
} }
/**
* @deprecated Use {@link #addAuxiliaryDatabaseObjects(JavaType, BasicValueConverter, Size, Database, JdbcTypeIndicators)} instead
*/
@Incubating
@Deprecated(forRemoval = true)
default void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
}
/** /**
* Add auxiliary database objects for this {@linkplain JdbcType} to the {@link Database} object. * Add auxiliary database objects for this {@linkplain JdbcType} to the {@link Database} object.
* *
@ -396,7 +384,6 @@ public interface JdbcType extends Serializable {
Size columnSize, Size columnSize,
Database database, Database database,
JdbcTypeIndicators context) { JdbcTypeIndicators context) {
addAuxiliaryDatabaseObjects( javaType, columnSize, database, context.getTypeConfiguration() );
} }
@Incubating @Incubating

View File

@ -46,9 +46,7 @@ public class ArrayDdlTypeImpl extends DdlTypeImpl {
dialect.getSizeStrategy().resolveSize( dialect.getSizeStrategy().resolveSize(
elementType.getJdbcMapping().getJdbcType(), elementType.getJdbcMapping().getJdbcType(),
elementType.getJavaTypeDescriptor(), elementType.getJavaTypeDescriptor(),
columnSize.getPrecision(), columnSize
columnSize.getScale(),
columnSize.getLength()
), ),
elementType, elementType,
ddlTypeRegistry ddlTypeRegistry
@ -79,9 +77,7 @@ public class ArrayDdlTypeImpl extends DdlTypeImpl {
dialect.getSizeStrategy().resolveSize( dialect.getSizeStrategy().resolveSize(
elementType.getJdbcMapping().getJdbcType(), elementType.getJdbcMapping().getJdbcType(),
elementType.getJavaTypeDescriptor(), elementType.getJavaTypeDescriptor(),
columnSize.getPrecision(), columnSize
columnSize.getScale(),
columnSize.getLength()
), ),
elementType elementType
); );

View File

@ -114,8 +114,7 @@ public class DdlTypeImpl implements DdlType {
} }
else { else {
//use the given length/precision/scale //use the given length/precision/scale
final Size size = dialect.getSizeStrategy() final Size size = dialect.getSizeStrategy().resolveSize( jdbcType, javaType, precision, scale, length );
.resolveSize( jdbcType, javaType, precision, scale, length );
if ( size.getPrecision() != null && size.getScale() == null ) { if ( size.getPrecision() != null && size.getScale() == null ) {
//needed for cast(x as BigInteger(p)) //needed for cast(x as BigInteger(p))
size.setScale( javaType.getDefaultSqlScale( dialect, jdbcType ) ); size.setScale( javaType.getDefaultSqlScale( dialect, jdbcType ) );