HHH-17904 Introduce config property to enable native enum type

This commit is contained in:
Christian Beikov 2024-03-28 13:35:56 +01:00
parent 5d16b90826
commit 94f17a92e0
18 changed files with 119 additions and 4 deletions

View File

@ -222,7 +222,8 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
private final SqmTranslatorFactory sqmTranslatorFactory; private final SqmTranslatorFactory sqmTranslatorFactory;
private final Boolean useOfJdbcNamedParametersEnabled; private final Boolean useOfJdbcNamedParametersEnabled;
private boolean namedQueryStartupCheckingEnabled; private boolean namedQueryStartupCheckingEnabled;
private boolean preferJavaTimeJdbcTypes; private final boolean preferJavaTimeJdbcTypes;
private final boolean preferNativeEnumTypes;
private final int preferredSqlTypeCodeForBoolean; private final int preferredSqlTypeCodeForBoolean;
private final int preferredSqlTypeCodeForDuration; private final int preferredSqlTypeCodeForDuration;
private final int preferredSqlTypeCodeForUuid; private final int preferredSqlTypeCodeForUuid;
@ -445,6 +446,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.namedQueryStartupCheckingEnabled = configurationService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true ); this.namedQueryStartupCheckingEnabled = configurationService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true );
this.preferJavaTimeJdbcTypes = MetadataBuildingContext.isPreferJavaTimeJdbcTypesEnabled( configurationService ); this.preferJavaTimeJdbcTypes = MetadataBuildingContext.isPreferJavaTimeJdbcTypesEnabled( configurationService );
this.preferNativeEnumTypes = MetadataBuildingContext.isPreferNativeEnumTypesEnabled( configurationService );
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry ); this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
this.preferredSqlTypeCodeForDuration = ConfigurationHelper.getPreferredSqlTypeCodeForDuration( serviceRegistry ); this.preferredSqlTypeCodeForDuration = ConfigurationHelper.getPreferredSqlTypeCodeForDuration( serviceRegistry );
this.preferredSqlTypeCodeForUuid = ConfigurationHelper.getPreferredSqlTypeCodeForUuid( serviceRegistry ); this.preferredSqlTypeCodeForUuid = ConfigurationHelper.getPreferredSqlTypeCodeForUuid( serviceRegistry );
@ -1288,6 +1290,11 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
return preferJavaTimeJdbcTypes; return preferJavaTimeJdbcTypes;
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return preferNativeEnumTypes;
}
@Override @Override
public FormatMapper getJsonFormatMapper() { public FormatMapper getJsonFormatMapper() {
return jsonFormatMapper; return jsonFormatMapper;

View File

@ -223,6 +223,11 @@ public class BasicValueBinder implements JdbcTypeIndicators {
return buildingContext.isPreferJavaTimeJdbcTypesEnabled(); return buildingContext.isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return buildingContext.isPreferNativeEnumTypesEnabled();
}
@Override @Override
public int getPreferredSqlTypeCodeForBoolean() { public int getPreferredSqlTypeCodeForBoolean() {
return resolveJdbcTypeCode( buildingContext.getPreferredSqlTypeCodeForBoolean() ); return resolveJdbcTypeCode( buildingContext.getPreferredSqlTypeCodeForBoolean() );

View File

@ -65,6 +65,11 @@ public class VersionResolution<E> implements BasicValue.Resolution<E> {
return context.isPreferJavaTimeJdbcTypesEnabled(); return context.isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return context.isPreferNativeEnumTypesEnabled();
}
@Override @Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() { public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return BasicValue.timeZoneStorageStrategy( timeZoneStorageType, context ); return BasicValue.timeZoneStorageStrategy( timeZoneStorageType, context );

View File

@ -493,6 +493,11 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
return delegate.isPreferJavaTimeJdbcTypesEnabled(); return delegate.isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return delegate.isPreferNativeEnumTypesEnabled();
}
@Override @Override
public FormatMapper getJsonFormatMapper() { public FormatMapper getJsonFormatMapper() {
return delegate.getJsonFormatMapper(); return delegate.getJsonFormatMapper();

View File

@ -85,10 +85,19 @@ public interface MetadataBuildingContext {
return isPreferJavaTimeJdbcTypesEnabled( getBootstrapContext().getServiceRegistry() ); return isPreferJavaTimeJdbcTypesEnabled( getBootstrapContext().getServiceRegistry() );
} }
@Incubating
default boolean isPreferNativeEnumTypesEnabled() {
return isPreferNativeEnumTypesEnabled( getBootstrapContext().getServiceRegistry() );
}
static boolean isPreferJavaTimeJdbcTypesEnabled(ServiceRegistry serviceRegistry) { static boolean isPreferJavaTimeJdbcTypesEnabled(ServiceRegistry serviceRegistry) {
return isPreferJavaTimeJdbcTypesEnabled( serviceRegistry.requireService( ConfigurationService.class ) ); return isPreferJavaTimeJdbcTypesEnabled( serviceRegistry.requireService( ConfigurationService.class ) );
} }
static boolean isPreferNativeEnumTypesEnabled(ServiceRegistry serviceRegistry) {
return isPreferNativeEnumTypesEnabled( serviceRegistry.requireService( ConfigurationService.class ) );
}
static boolean isPreferJavaTimeJdbcTypesEnabled(ConfigurationService configurationService) { static boolean isPreferJavaTimeJdbcTypesEnabled(ConfigurationService configurationService) {
return ConfigurationHelper.getBoolean( return ConfigurationHelper.getBoolean(
MappingSettings.PREFER_JAVA_TYPE_JDBC_TYPES, MappingSettings.PREFER_JAVA_TYPE_JDBC_TYPES,
@ -98,6 +107,15 @@ public interface MetadataBuildingContext {
); );
} }
static boolean isPreferNativeEnumTypesEnabled(ConfigurationService configurationService) {
return ConfigurationHelper.getBoolean(
MappingSettings.PREFER_NATIVE_ENUM_TYPES,
configurationService.getSettings(),
// todo: switch to true with HHH-17905
false
);
}
TypeDefinitionRegistry getTypeDefinitionRegistry(); TypeDefinitionRegistry getTypeDefinitionRegistry();
/** /**

View File

@ -345,6 +345,8 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
boolean isPreferJavaTimeJdbcTypesEnabled(); boolean isPreferJavaTimeJdbcTypesEnabled();
boolean isPreferNativeEnumTypesEnabled();
/** /**
* The format mapper to use for serializing/deserializing JSON data. * The format mapper to use for serializing/deserializing JSON data.
* *

View File

@ -242,6 +242,21 @@ public interface MappingSettings {
@Incubating @Incubating
String PREFER_JAVA_TYPE_JDBC_TYPES = "hibernate.type.prefer_java_type_jdbc_types"; String PREFER_JAVA_TYPE_JDBC_TYPES = "hibernate.type.prefer_java_type_jdbc_types";
/**
* Indicates whether to prefer using SQL enums and the respective special JDBC types for binding/extracting
* of values.
* <p/>
* Used to set the value across the entire system as opposed to scattered, individual
* {@linkplain org.hibernate.annotations.JdbcTypeCode} and {@linkplain org.hibernate.annotations.JdbcType}
* naming specific {@linkplain org.hibernate.type.descriptor.jdbc.JdbcType} implementations.
*
* @settingDefault false
*
* @since 6.5
*/
@Incubating
String PREFER_NATIVE_ENUM_TYPES = "hibernate.type.prefer_native_enum_types";
/** /**
* Specifies a {@link org.hibernate.type.format.FormatMapper} used for JSON * Specifies a {@link org.hibernate.type.format.FormatMapper} used for JSON
* serialization and deserialization, either: * serialization and deserialization, either:

View File

@ -1111,6 +1111,11 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
return getBuildingContext().isPreferJavaTimeJdbcTypesEnabled(); return getBuildingContext().isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return getBuildingContext().isPreferNativeEnumTypesEnabled();
}
@Override @Override
public Object accept(ValueVisitor visitor) { public Object accept(ValueVisitor visitor) {
return visitor.accept(this); return visitor.accept(this);

View File

@ -40,13 +40,14 @@ public class EnumJavaType<T extends Enum<T>> extends AbstractClassJavaType<T> {
public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) { public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
final JdbcTypeRegistry jdbcTypeRegistry = context.getTypeConfiguration().getJdbcTypeRegistry(); final JdbcTypeRegistry jdbcTypeRegistry = context.getTypeConfiguration().getJdbcTypeRegistry();
final EnumType type = context.getEnumeratedType(); final EnumType type = context.getEnumeratedType();
final boolean preferNativeEnumTypesEnabled = context.isPreferNativeEnumTypesEnabled();
int sqlType; int sqlType;
switch ( type == null ? ORDINAL : type ) { switch ( type == null ? ORDINAL : type ) {
case ORDINAL: case ORDINAL:
if ( jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) { if ( preferNativeEnumTypesEnabled && jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) {
sqlType = ENUM; sqlType = ENUM;
} }
else if ( jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) { else if ( preferNativeEnumTypesEnabled && jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) {
sqlType = NAMED_ENUM; sqlType = NAMED_ENUM;
} }
else { else {
@ -57,7 +58,7 @@ public class EnumJavaType<T extends Enum<T>> extends AbstractClassJavaType<T> {
if ( jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) { if ( jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) {
sqlType = ENUM; sqlType = ENUM;
} }
else if ( jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) { else if ( preferNativeEnumTypesEnabled && jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) {
sqlType = NAMED_ENUM; sqlType = NAMED_ENUM;
} }
else if ( context.getColumnLength() == 1 ) { else if ( context.getColumnLength() == 1 ) {

View File

@ -47,6 +47,11 @@ public class DelegatingJdbcTypeIndicators implements JdbcTypeIndicators {
return delegate.isPreferJavaTimeJdbcTypesEnabled(); return delegate.isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return delegate.isPreferNativeEnumTypesEnabled();
}
@Override @Override
public int getPreferredSqlTypeCodeForBoolean() { public int getPreferredSqlTypeCodeForBoolean() {
return delegate.getPreferredSqlTypeCodeForBoolean(); return delegate.getPreferredSqlTypeCodeForBoolean();

View File

@ -76,6 +76,13 @@ public interface JdbcTypeIndicators {
return getCurrentBaseSqlTypeIndicators().isPreferJavaTimeJdbcTypesEnabled(); return getCurrentBaseSqlTypeIndicators().isPreferJavaTimeJdbcTypesEnabled();
} }
/**
* @see org.hibernate.cfg.MappingSettings#PREFER_NATIVE_ENUM_TYPES
*/
default boolean isPreferNativeEnumTypesEnabled() {
return getCurrentBaseSqlTypeIndicators().isPreferNativeEnumTypesEnabled();
}
/** /**
* When mapping a boolean type to the database what is the preferred SQL type code to use? * When mapping a boolean type to the database what is the preferred SQL type code to use?
* <p> * <p>

View File

@ -429,6 +429,13 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
: sessionFactory.getSessionFactoryOptions().isPreferJavaTimeJdbcTypesEnabled(); : sessionFactory.getSessionFactoryOptions().isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return sessionFactory == null
? metadataBuildingContext.isPreferNativeEnumTypesEnabled()
: sessionFactory.getSessionFactoryOptions().isPreferNativeEnumTypesEnabled();
}
@Override @Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() { public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return sessionFactory == null return sessionFactory == null

View File

@ -11,6 +11,8 @@ import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Root;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.type.descriptor.JdbcBindingLogging; import org.hibernate.type.descriptor.JdbcBindingLogging;
import org.hibernate.type.descriptor.JdbcExtractingLogging; import org.hibernate.type.descriptor.JdbcExtractingLogging;
@ -60,6 +62,12 @@ public class EnumTypeTest extends BaseCoreFunctionalTestCase {
return new String[] { "org/hibernate/orm/test/mapping/converted/enums/Person.hbm.xml" }; return new String[] { "org/hibernate/orm/test/mapping/converted/enums/Person.hbm.xml" };
} }
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( Environment.PREFER_NATIVE_ENUM_TYPES, "false" );
}
@Override @Override
protected void prepareTest() { protected void prepareTest() {
doInHibernate( this::sessionFactory, s -> { doInHibernate( this::sessionFactory, s -> {

View File

@ -42,6 +42,7 @@ public class UnspecifiedEnumTypeTest extends BaseCoreFunctionalTestCase {
protected void configure(Configuration configuration) { protected void configure(Configuration configuration) {
super.configure( configuration ); super.configure( configuration );
configuration.setProperty( Environment.HBM2DDL_AUTO, "" ); configuration.setProperty( Environment.HBM2DDL_AUTO, "" );
configuration.setProperty( Environment.PREFER_NATIVE_ENUM_TYPES, "false" );
} }
@Before @Before

View File

@ -43,6 +43,7 @@ public class UnspecifiedEnumTypeTest extends BaseEnversFunctionalTestCase {
settings.put( AvailableSettings.SHOW_SQL, "true" ); settings.put( AvailableSettings.SHOW_SQL, "true" );
settings.put( AvailableSettings.FORMAT_SQL, "true" ); settings.put( AvailableSettings.FORMAT_SQL, "true" );
settings.put( AvailableSettings.PREFER_NATIVE_ENUM_TYPES, "false" );
} }
@Test @Test

View File

@ -9,9 +9,12 @@ package org.hibernate.orm.test.envers.integration.collection;
import java.sql.Types; import java.sql.Types;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping; import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
@ -42,6 +45,12 @@ public class EnumSet extends BaseEnversJPAFunctionalTestCase {
return new Class[] {EnumSetEntity.class}; return new Class[] {EnumSetEntity.class};
} }
@Override
protected void addConfigOptions(Map options) {
super.addConfigOptions( options );
options.put( AvailableSettings.PREFER_NATIVE_ENUM_TYPES, "false" );
}
@Test @Test
@Priority(10) @Priority(10)
public void initData() { public void initData() {

View File

@ -6,6 +6,9 @@
*/ */
package org.hibernate.orm.test.envers.integration.customtype; package org.hibernate.orm.test.envers.integration.customtype;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase; import org.hibernate.orm.test.envers.BaseEnversJPAFunctionalTestCase;
import org.hibernate.orm.test.envers.Priority; import org.hibernate.orm.test.envers.Priority;
import org.hibernate.orm.test.envers.entities.customtype.EnumTypeEntity; import org.hibernate.orm.test.envers.entities.customtype.EnumTypeEntity;
@ -26,6 +29,12 @@ public class EnumTypeTest extends BaseEnversJPAFunctionalTestCase {
return new Class<?>[] {EnumTypeEntity.class}; return new Class<?>[] {EnumTypeEntity.class};
} }
@Override
protected void addConfigOptions(Map options) {
super.addConfigOptions( options );
options.put( AvailableSettings.PREFER_NATIVE_ENUM_TYPES, "false" );
}
@Test @Test
@Priority(10) @Priority(10)
public void initData() { public void initData() {

View File

@ -405,6 +405,11 @@ public abstract class MockSessionFactory
return MetadataBuildingContext.super.isPreferJavaTimeJdbcTypesEnabled(); return MetadataBuildingContext.super.isPreferJavaTimeJdbcTypesEnabled();
} }
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return MetadataBuildingContext.super.isPreferNativeEnumTypesEnabled();
}
@Override @Override
public FastSessionServices getFastSessionServices() { public FastSessionServices getFastSessionServices() {
throw new UnsupportedOperationException("operation not supported"); throw new UnsupportedOperationException("operation not supported");