HHH-15912 adaptively choose the DDL type for ORDINAL enums based on the number of members
this amounts to a reversion of HHH-15288 for 99.99% of enums
This commit is contained in:
parent
7007bafe55
commit
5089df2036
|
@ -25,7 +25,6 @@ import org.hibernate.type.AdjustableBasicType;
|
|||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.type.SerializableType;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaType;
|
||||
import org.hibernate.type.descriptor.java.EnumJavaType;
|
||||
|
@ -38,6 +37,9 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
|
|||
import org.hibernate.type.descriptor.jdbc.ObjectJdbcType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.type.SqlTypes.SMALLINT;
|
||||
import static org.hibernate.type.SqlTypes.TINYINT;
|
||||
|
||||
/**
|
||||
* BasicValue.Resolution resolver for cases where no explicit
|
||||
* type info was supplied.
|
||||
|
@ -344,19 +346,19 @@ public class InferredBasicValueResolver {
|
|||
TypeConfiguration typeConfiguration) {
|
||||
return ordinalResolution(
|
||||
enumJavaType,
|
||||
integerJavaType( explicitJavaType, typeConfiguration ),
|
||||
integerJdbcType( explicitJdbcType, typeConfiguration ),
|
||||
ordinalJavaType( explicitJavaType, typeConfiguration ),
|
||||
ordinalJdbcType( explicitJdbcType, enumJavaType, typeConfiguration ),
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
private static JdbcType integerJdbcType(JdbcType explicitJdbcType, TypeConfiguration typeConfiguration) {
|
||||
private static JdbcType ordinalJdbcType(JdbcType explicitJdbcType, EnumJavaType<?> enumJavaType, TypeConfiguration typeConfiguration) {
|
||||
return explicitJdbcType != null
|
||||
? explicitJdbcType
|
||||
: typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.SMALLINT );
|
||||
: typeConfiguration.getJdbcTypeRegistry().getDescriptor( enumJavaType.hasManyValues() ? SMALLINT : TINYINT );
|
||||
}
|
||||
|
||||
private static <N extends Number> JavaType<N> integerJavaType(JavaType<N> explicitJavaType, TypeConfiguration typeConfiguration) {
|
||||
private static <N extends Number> JavaType<N> ordinalJavaType(JavaType<N> explicitJavaType, TypeConfiguration typeConfiguration) {
|
||||
if ( explicitJavaType != null ) {
|
||||
if ( !Integer.class.isAssignableFrom( explicitJavaType.getJavaTypeClass() ) ) {
|
||||
throw new MappingException(
|
||||
|
|
|
@ -1326,7 +1326,6 @@ public abstract class Dialect implements ConversionContext {
|
|||
public boolean equivalentTypes(int typeCode1, int typeCode2) {
|
||||
return typeCode1==typeCode2
|
||||
|| isNumericOrDecimal(typeCode1) && isNumericOrDecimal(typeCode2)
|
||||
|| isSmallOrTinyInt(typeCode1) && isSmallOrTinyInt(typeCode2) //special case for HHH-15288 migration
|
||||
// || isIntegral(typeCode1) && isIntegral(typeCode2)
|
||||
|| isFloatOrRealOrDouble(typeCode1) && isFloatOrRealOrDouble(typeCode2)
|
||||
|| isVarcharType(typeCode1) && isVarcharType(typeCode2)
|
||||
|
|
|
@ -6,15 +6,22 @@
|
|||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Types;
|
||||
import jakarta.persistence.EnumType;
|
||||
|
||||
import org.hibernate.type.SqlTypes;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||
|
||||
import static jakarta.persistence.EnumType.ORDINAL;
|
||||
import static org.hibernate.type.SqlTypes.CHAR;
|
||||
import static org.hibernate.type.SqlTypes.NCHAR;
|
||||
import static org.hibernate.type.SqlTypes.NVARCHAR;
|
||||
import static org.hibernate.type.SqlTypes.SMALLINT;
|
||||
import static org.hibernate.type.SqlTypes.TINYINT;
|
||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||
|
||||
/**
|
||||
* Describes a Java {@code enum} type.
|
||||
*
|
||||
|
@ -27,21 +34,27 @@ public class EnumJavaType<T extends Enum<T>> extends AbstractClassJavaType<T> {
|
|||
|
||||
@Override
|
||||
public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
|
||||
JdbcTypeRegistry registry = context.getTypeConfiguration().getJdbcTypeRegistry();
|
||||
if ( context.getEnumeratedType() != null && context.getEnumeratedType() == EnumType.STRING ) {
|
||||
final JdbcTypeRegistry registry = context.getTypeConfiguration().getJdbcTypeRegistry();
|
||||
final EnumType type = context.getEnumeratedType();
|
||||
switch ( type == null ? ORDINAL : type ) {
|
||||
case ORDINAL:
|
||||
return registry.getDescriptor( hasManyValues() ? SMALLINT : TINYINT );
|
||||
case STRING:
|
||||
if ( context.getColumnLength() == 1 ) {
|
||||
return context.isNationalized()
|
||||
? registry.getDescriptor( Types.NCHAR )
|
||||
: registry.getDescriptor( Types.CHAR );
|
||||
? registry.getDescriptor( NCHAR )
|
||||
: registry.getDescriptor( CHAR );
|
||||
}
|
||||
return context.isNationalized()
|
||||
? registry.getDescriptor( NVARCHAR )
|
||||
: registry.getDescriptor( VARCHAR );
|
||||
default:
|
||||
throw new AssertionFailure("unknown EnumType");
|
||||
}
|
||||
}
|
||||
|
||||
return context.isNationalized()
|
||||
? registry.getDescriptor( Types.NVARCHAR )
|
||||
: registry.getDescriptor( Types.VARCHAR );
|
||||
}
|
||||
else {
|
||||
return registry.getDescriptor( SqlTypes.SMALLINT );
|
||||
}
|
||||
public boolean hasManyValues() {
|
||||
return getJavaTypeClass().getEnumConstants().length > 128; // a bit arbitrary, but gives us some headroom
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,7 +79,7 @@ public class EnumeratedSmokeTest extends BaseUnitTestCase {
|
|||
assertThat( hibernateMappingEnumType.isOrdinal(), is(expectedJpaEnumType==EnumType.ORDINAL) );
|
||||
final int expectedJdbcTypeCode = jdbcRegistry.getDescriptor(
|
||||
expectedJpaEnumType == EnumType.ORDINAL ?
|
||||
Types.SMALLINT :
|
||||
Types.TINYINT :
|
||||
Types.VARCHAR
|
||||
).getJdbcTypeCode();
|
||||
assertThat(
|
||||
|
|
|
@ -60,7 +60,7 @@ public class EnumResolutionTests {
|
|||
|
||||
verifyEnumResolution(
|
||||
entityBinding.getProperty( "rawEnum" ),
|
||||
Types.SMALLINT,
|
||||
Types.TINYINT,
|
||||
Integer.class,
|
||||
OrdinalEnumValueConverter.class,
|
||||
true
|
||||
|
@ -75,7 +75,7 @@ public class EnumResolutionTests {
|
|||
|
||||
verifyEnumResolution(
|
||||
entityBinding.getProperty( "unspecifiedMappingEnum" ),
|
||||
Types.SMALLINT,
|
||||
Types.TINYINT,
|
||||
Integer.class,
|
||||
OrdinalEnumValueConverter.class,
|
||||
true
|
||||
|
@ -90,7 +90,7 @@ public class EnumResolutionTests {
|
|||
|
||||
verifyEnumResolution(
|
||||
entityBinding.getProperty( "ordinalEnum" ),
|
||||
Types.SMALLINT,
|
||||
Types.TINYINT,
|
||||
Integer.class,
|
||||
OrdinalEnumValueConverter.class,
|
||||
true
|
||||
|
@ -143,7 +143,7 @@ public class EnumResolutionTests {
|
|||
|
||||
verifyEnumResolution(
|
||||
entityBinding.getProperty( "explicitEnum" ),
|
||||
Types.TINYINT,
|
||||
Types.SMALLINT,
|
||||
Integer.class,
|
||||
OrdinalEnumValueConverter.class,
|
||||
true
|
||||
|
@ -222,7 +222,7 @@ public class EnumResolutionTests {
|
|||
private Values namedEnum;
|
||||
|
||||
@Enumerated( ORDINAL )
|
||||
@JdbcTypeCode( Types.TINYINT )
|
||||
@JdbcTypeCode( Types.SMALLINT )
|
||||
private Values explicitEnum;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ public class SmokeTests {
|
|||
|
||||
assertThat(
|
||||
jdbcTypeRegistry.getDescriptor( valueConverter.getJdbcTypeCode() ),
|
||||
is( jdbcTypeRegistry.getDescriptor( Types.SMALLINT ) )
|
||||
is( jdbcTypeRegistry.getDescriptor( Types.TINYINT ) )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ public class SmokeTests {
|
|||
assertThat( enumConverter.getRelationalJavaType().getJavaTypeClass(), AssignableMatcher.assignableTo( Integer.class ) );
|
||||
assertThat(
|
||||
basicType.getJdbcType(),
|
||||
is( jdbcTypeRegistry.getDescriptor( Types.SMALLINT ) )
|
||||
is( jdbcTypeRegistry.getDescriptor( Types.TINYINT ) )
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
package org.hibernate.orm.test.type;
|
||||
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
|
||||
|
@ -24,8 +27,6 @@ import jakarta.persistence.Query;
|
|||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
@ -113,6 +114,9 @@ public class EnumArrayTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
@Test
|
||||
@SkipForDialect( value = HSQLDialect.class, comment = "HSQL does not like plain parameters in the distinct from predicate")
|
||||
@SkipForDialect( value = OracleDialect.class, comment = "Oracle requires a special function to compare XML")
|
||||
@SkipForDialect( value = MySQLDialect.class )
|
||||
@SkipForDialect( value = DerbyDialect.class )
|
||||
@SkipForDialect( value = DB2Dialect.class )
|
||||
public void testNativeQuery() {
|
||||
inSession( em -> {
|
||||
final String op = em.getJdbcServices().getDialect().supportsDistinctFromPredicate() ? "IS NOT DISTINCT FROM" : "=";
|
||||
|
|
Loading…
Reference in New Issue