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 95641b2366
commit d423b52be3
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 Boolean useOfJdbcNamedParametersEnabled;
private boolean namedQueryStartupCheckingEnabled;
private boolean preferJavaTimeJdbcTypes;
private final boolean preferJavaTimeJdbcTypes;
private final boolean preferNativeEnumTypes;
private final int preferredSqlTypeCodeForBoolean;
private final int preferredSqlTypeCodeForDuration;
private final int preferredSqlTypeCodeForUuid;
@ -445,6 +446,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.namedQueryStartupCheckingEnabled = configurationService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true );
this.preferJavaTimeJdbcTypes = MetadataBuildingContext.isPreferJavaTimeJdbcTypesEnabled( configurationService );
this.preferNativeEnumTypes = MetadataBuildingContext.isPreferNativeEnumTypesEnabled( configurationService );
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
this.preferredSqlTypeCodeForDuration = ConfigurationHelper.getPreferredSqlTypeCodeForDuration( serviceRegistry );
this.preferredSqlTypeCodeForUuid = ConfigurationHelper.getPreferredSqlTypeCodeForUuid( serviceRegistry );
@ -1288,6 +1290,11 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
return preferJavaTimeJdbcTypes;
}
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return preferNativeEnumTypes;
}
@Override
public FormatMapper getJsonFormatMapper() {
return jsonFormatMapper;

View File

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

View File

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

View File

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

View File

@ -85,10 +85,19 @@ public interface MetadataBuildingContext {
return isPreferJavaTimeJdbcTypesEnabled( getBootstrapContext().getServiceRegistry() );
}
@Incubating
default boolean isPreferNativeEnumTypesEnabled() {
return isPreferNativeEnumTypesEnabled( getBootstrapContext().getServiceRegistry() );
}
static boolean isPreferJavaTimeJdbcTypesEnabled(ServiceRegistry serviceRegistry) {
return isPreferJavaTimeJdbcTypesEnabled( serviceRegistry.requireService( ConfigurationService.class ) );
}
static boolean isPreferNativeEnumTypesEnabled(ServiceRegistry serviceRegistry) {
return isPreferNativeEnumTypesEnabled( serviceRegistry.requireService( ConfigurationService.class ) );
}
static boolean isPreferJavaTimeJdbcTypesEnabled(ConfigurationService configurationService) {
return ConfigurationHelper.getBoolean(
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();
/**

View File

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

View File

@ -242,6 +242,21 @@ public interface MappingSettings {
@Incubating
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
* serialization and deserialization, either:

View File

@ -1110,6 +1110,11 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
return getBuildingContext().isPreferJavaTimeJdbcTypesEnabled();
}
@Override
public boolean isPreferNativeEnumTypesEnabled() {
return getBuildingContext().isPreferNativeEnumTypesEnabled();
}
@Override
public Object accept(ValueVisitor visitor) {
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) {
final JdbcTypeRegistry jdbcTypeRegistry = context.getTypeConfiguration().getJdbcTypeRegistry();
final EnumType type = context.getEnumeratedType();
final boolean preferNativeEnumTypesEnabled = context.isPreferNativeEnumTypesEnabled();
int sqlType;
switch ( type == null ? ORDINAL : type ) {
case ORDINAL:
if ( jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) {
if ( preferNativeEnumTypesEnabled && jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) {
sqlType = ENUM;
}
else if ( jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) {
else if ( preferNativeEnumTypesEnabled && jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) {
sqlType = NAMED_ENUM;
}
else {
@ -57,7 +58,7 @@ public class EnumJavaType<T extends Enum<T>> extends AbstractClassJavaType<T> {
if ( jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ) {
sqlType = ENUM;
}
else if ( jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) {
else if ( preferNativeEnumTypesEnabled && jdbcTypeRegistry.hasRegisteredDescriptor( NAMED_ENUM ) ) {
sqlType = NAMED_ENUM;
}
else if ( context.getColumnLength() == 1 ) {

View File

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

View File

@ -76,6 +76,13 @@ public interface JdbcTypeIndicators {
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?
* <p>

View File

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

View File

@ -11,6 +11,8 @@ import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.type.descriptor.JdbcBindingLogging;
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" };
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( Environment.PREFER_NATIVE_ENUM_TYPES, "false" );
}
@Override
protected void prepareTest() {
doInHibernate( this::sessionFactory, s -> {

View File

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

View File

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

View File

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

View File

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

View File

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