remove hibernate.query.conventional_java_constants
this was apparently a sorta nasty bandaid to a performance problem in query compilation and it caused problems for some users, breaking interpretation of enum values
This commit is contained in:
parent
a84793bd6d
commit
a59bf70ccf
|
@ -564,16 +564,6 @@ It follows a pattern similar to the ANSI SQL definition of the global temporary
|
||||||
+
|
+
|
||||||
This configuration property defines the database catalog used for storing the temporary tables used for bulk HQL operations.
|
This configuration property defines the database catalog used for storing the temporary tables used for bulk HQL operations.
|
||||||
|
|
||||||
`*hibernate.query.conventional_java_constants*` (e.g. `true` (default value) or `false`)::
|
|
||||||
Setting which indicates whether or not Java constants follow the https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html[Java Naming conventions].
|
|
||||||
+
|
|
||||||
The default is `true`.
|
|
||||||
Existing applications may want to disable this (set it `false`) if non-conventional Java constants are used.
|
|
||||||
However, there is a significant performance overhead for using non-conventional Java constants
|
|
||||||
since Hibernate cannot determine if aliases should be treated as Java constants or not.
|
|
||||||
+
|
|
||||||
Check out https://hibernate.atlassian.net/browse/HHH-4959[HHH-4959] for more details.
|
|
||||||
|
|
||||||
[[configurations-batch]]
|
[[configurations-batch]]
|
||||||
=== Batching properties
|
=== Batching properties
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,6 @@ import static org.hibernate.cfg.AvailableSettings.CACHE_REGION_PREFIX;
|
||||||
import static org.hibernate.cfg.AvailableSettings.CALLABLE_NAMED_PARAMS_ENABLED;
|
import static org.hibernate.cfg.AvailableSettings.CALLABLE_NAMED_PARAMS_ENABLED;
|
||||||
import static org.hibernate.cfg.AvailableSettings.CHECK_NULLABILITY;
|
import static org.hibernate.cfg.AvailableSettings.CHECK_NULLABILITY;
|
||||||
import static org.hibernate.cfg.AvailableSettings.CONNECTION_HANDLING;
|
import static org.hibernate.cfg.AvailableSettings.CONNECTION_HANDLING;
|
||||||
import static org.hibernate.cfg.AvailableSettings.CONVENTIONAL_JAVA_CONSTANTS;
|
|
||||||
import static org.hibernate.cfg.AvailableSettings.CRITERIA_VALUE_HANDLING_MODE;
|
import static org.hibernate.cfg.AvailableSettings.CRITERIA_VALUE_HANDLING_MODE;
|
||||||
import static org.hibernate.cfg.AvailableSettings.CUSTOM_ENTITY_DIRTINESS_STRATEGY;
|
import static org.hibernate.cfg.AvailableSettings.CUSTOM_ENTITY_DIRTINESS_STRATEGY;
|
||||||
import static org.hibernate.cfg.AvailableSettings.DEFAULT_BATCH_FETCH_SIZE;
|
import static org.hibernate.cfg.AvailableSettings.DEFAULT_BATCH_FETCH_SIZE;
|
||||||
|
@ -220,7 +219,6 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
||||||
private SqmTranslatorFactory sqmTranslatorFactory;
|
private SqmTranslatorFactory sqmTranslatorFactory;
|
||||||
private Boolean useOfJdbcNamedParametersEnabled;
|
private Boolean useOfJdbcNamedParametersEnabled;
|
||||||
private boolean namedQueryStartupCheckingEnabled;
|
private boolean namedQueryStartupCheckingEnabled;
|
||||||
private boolean conventionalJavaConstants;
|
|
||||||
private final boolean omitJoinOfSuperclassTablesEnabled;
|
private final boolean omitJoinOfSuperclassTablesEnabled;
|
||||||
private final int preferredSqlTypeCodeForBoolean;
|
private final int preferredSqlTypeCodeForBoolean;
|
||||||
private final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy;
|
private final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy;
|
||||||
|
@ -441,14 +439,12 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
||||||
this.useOfJdbcNamedParametersEnabled = cfgService.getSetting( CALLABLE_NAMED_PARAMS_ENABLED, BOOLEAN, true );
|
this.useOfJdbcNamedParametersEnabled = cfgService.getSetting( CALLABLE_NAMED_PARAMS_ENABLED, BOOLEAN, true );
|
||||||
|
|
||||||
this.namedQueryStartupCheckingEnabled = cfgService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true );
|
this.namedQueryStartupCheckingEnabled = cfgService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true );
|
||||||
this.conventionalJavaConstants = cfgService.getSetting(
|
|
||||||
CONVENTIONAL_JAVA_CONSTANTS, BOOLEAN, true );
|
|
||||||
this.omitJoinOfSuperclassTablesEnabled = cfgService.getSetting( OMIT_JOIN_OF_SUPERCLASS_TABLES, BOOLEAN, true );
|
this.omitJoinOfSuperclassTablesEnabled = cfgService.getSetting( OMIT_JOIN_OF_SUPERCLASS_TABLES, BOOLEAN, true );
|
||||||
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
|
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
|
||||||
this.defaultTimeZoneStorageStrategy = context.getMetadataBuildingOptions().getDefaultTimeZoneStorage();
|
this.defaultTimeZoneStorageStrategy = context.getMetadataBuildingOptions().getDefaultTimeZoneStorage();
|
||||||
|
|
||||||
final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
|
final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
|
||||||
if ( !NoCachingRegionFactory.class.isInstance( regionFactory ) ) {
|
if ( !(regionFactory instanceof NoCachingRegionFactory) ) {
|
||||||
this.secondLevelCacheEnabled = cfgService.getSetting( USE_SECOND_LEVEL_CACHE, BOOLEAN, true );
|
this.secondLevelCacheEnabled = cfgService.getSetting( USE_SECOND_LEVEL_CACHE, BOOLEAN, true );
|
||||||
this.queryCacheEnabled = cfgService.getSetting( USE_QUERY_CACHE, BOOLEAN, false );
|
this.queryCacheEnabled = cfgService.getSetting( USE_QUERY_CACHE, BOOLEAN, false );
|
||||||
this.timestampsCacheFactory = strategySelector.resolveDefaultableStrategy(
|
this.timestampsCacheFactory = strategySelector.resolveDefaultableStrategy(
|
||||||
|
@ -1047,11 +1043,6 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
||||||
return namedQueryStartupCheckingEnabled;
|
return namedQueryStartupCheckingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isConventionalJavaConstants() {
|
|
||||||
return conventionalJavaConstants;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecondLevelCacheEnabled() {
|
public boolean isSecondLevelCacheEnabled() {
|
||||||
return secondLevelCacheEnabled;
|
return secondLevelCacheEnabled;
|
||||||
|
|
|
@ -229,11 +229,6 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
|
||||||
return delegate.isNamedQueryStartupCheckingEnabled();
|
return delegate.isNamedQueryStartupCheckingEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isConventionalJavaConstants() {
|
|
||||||
return delegate.isConventionalJavaConstants();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowOutOfTransactionUpdateOperations() {
|
public boolean isAllowOutOfTransactionUpdateOperations() {
|
||||||
return delegate.isAllowOutOfTransactionUpdateOperations();
|
return delegate.isAllowOutOfTransactionUpdateOperations();
|
||||||
|
|
|
@ -189,8 +189,6 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
||||||
|
|
||||||
boolean isNamedQueryStartupCheckingEnabled();
|
boolean isNamedQueryStartupCheckingEnabled();
|
||||||
|
|
||||||
boolean isConventionalJavaConstants();
|
|
||||||
|
|
||||||
boolean isSecondLevelCacheEnabled();
|
boolean isSecondLevelCacheEnabled();
|
||||||
|
|
||||||
boolean isQueryCacheEnabled();
|
boolean isQueryCacheEnabled();
|
||||||
|
|
|
@ -985,18 +985,6 @@ public interface AvailableSettings {
|
||||||
*/
|
*/
|
||||||
String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
|
String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
|
||||||
|
|
||||||
/**
|
|
||||||
* Setting which indicates whether or not Java constant follow the Java Naming conventions.
|
|
||||||
* <p/>
|
|
||||||
* Default is {@code true}. Existing applications may want to disable this (set it {@code false})
|
|
||||||
* if unconventional Java constants are used. However, there is a significant performance overhead
|
|
||||||
* for using unconventional Java constants since Hibernate cannot determine if aliases should be
|
|
||||||
* treated as Java constants or not.
|
|
||||||
*
|
|
||||||
* @since 5.2
|
|
||||||
*/
|
|
||||||
String CONVENTIONAL_JAVA_CONSTANTS = "hibernate.query.conventional_java_constants";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable ordering of update statements by primary key value
|
* Enable ordering of update statements by primary key value
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -254,28 +254,6 @@ public final class ReflectHelper {
|
||||||
return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess( clazz, name, true ).getGetter();
|
return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess( clazz, name, true ).getGetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object getConstantValue(String name, SessionFactoryImplementor factory) {
|
|
||||||
boolean conventionalJavaConstants = factory.getSessionFactoryOptions().isConventionalJavaConstants();
|
|
||||||
Class clazz;
|
|
||||||
try {
|
|
||||||
if ( conventionalJavaConstants &&
|
|
||||||
!JAVA_CONSTANT_PATTERN.matcher( name ).find() ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ClassLoaderService classLoaderService = factory.getServiceRegistry().getService( ClassLoaderService.class );
|
|
||||||
clazz = classLoaderService.classForName( StringHelper.qualifier( name ) );
|
|
||||||
}
|
|
||||||
catch ( Throwable t ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return clazz.getField( StringHelper.unqualify( name ) ).get( null );
|
|
||||||
}
|
|
||||||
catch ( Throwable t ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the default (no arg) constructor from the given class.
|
* Retrieve the default (no arg) constructor from the given class.
|
||||||
*
|
*
|
||||||
|
|
|
@ -122,82 +122,6 @@ public class ReflectHelperTest {
|
||||||
when( serviceRegistryMock.getService( eq( ClassLoaderService.class ) ) ).thenReturn( classLoaderServiceMock );
|
when( serviceRegistryMock.getService( eq( ClassLoaderService.class ) ) ).thenReturn( classLoaderServiceMock );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_simpleAlias() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
|
|
||||||
Object value = ReflectHelper.getConstantValue( "alias.b", sessionFactoryImplementorMock);
|
|
||||||
assertNull(value);
|
|
||||||
verify(classLoaderServiceMock, never()).classForName( anyString() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_simpleAlias_non_conventional() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( false );
|
|
||||||
|
|
||||||
Object value = ReflectHelper.getConstantValue( "alias.b", sessionFactoryImplementorMock);
|
|
||||||
assertNull(value);
|
|
||||||
verify(classLoaderServiceMock, times(1)).classForName( eq( "alias" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_nestedAlias() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
|
|
||||||
Object value = ReflectHelper.getConstantValue( "alias.b.c", sessionFactoryImplementorMock);
|
|
||||||
assertNull(value);
|
|
||||||
verify(classLoaderServiceMock, never()).classForName( anyString() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_nestedAlias_non_conventional() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( false );
|
|
||||||
|
|
||||||
Object value = ReflectHelper.getConstantValue( "alias.b.c", sessionFactoryImplementorMock);
|
|
||||||
assertNull(value);
|
|
||||||
verify(classLoaderServiceMock, times(1)).classForName( eq( "alias.b" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_outerEnum() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
|
|
||||||
when( classLoaderServiceMock.classForName( "jakarta.persistence.FetchType" ) ).thenReturn( (Class) FetchType.class );
|
|
||||||
Object value = ReflectHelper.getConstantValue( "jakarta.persistence.FetchType.LAZY", sessionFactoryImplementorMock);
|
|
||||||
assertEquals( FetchType.LAZY, value );
|
|
||||||
verify(classLoaderServiceMock, times(1)).classForName( eq("jakarta.persistence.FetchType") );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_enumClass() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
|
|
||||||
when( classLoaderServiceMock.classForName( "org.hibernate.orm.test.internal.util.ReflectHelperTest$Status" ) ).thenReturn( (Class) Status.class );
|
|
||||||
Object value = ReflectHelper.getConstantValue( "org.hibernate.orm.test.internal.util.ReflectHelperTest$Status", sessionFactoryImplementorMock);
|
|
||||||
assertNull(value);
|
|
||||||
verify(classLoaderServiceMock, never()).classForName( eq("org.hibernate.internal.util") );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_nestedEnum() {
|
|
||||||
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
when( classLoaderServiceMock.classForName( "org.hibernate.orm.test.internal.util.ReflectHelperTest$Status" ) ).thenReturn( (Class) Status.class );
|
|
||||||
Object value = ReflectHelper.getConstantValue( "org.hibernate.orm.test.internal.util.ReflectHelperTest$Status.ON", sessionFactoryImplementorMock);
|
|
||||||
assertEquals( ON, value );
|
|
||||||
verify(classLoaderServiceMock, times(1)).classForName( eq("org.hibernate.orm.test.internal.util.ReflectHelperTest$Status") );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_constant_digits() {
|
|
||||||
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
when( classLoaderServiceMock.classForName( "org.hibernate.orm.test.internal.util.hib3rnat3.C0nst4nts३" ) ).thenReturn( (Class) C0nst4nts३.class );
|
|
||||||
Object value = ReflectHelper.getConstantValue( "org.hibernate.orm.test.internal.util.hib3rnat3.C0nst4nts३.ABC_DEF", sessionFactoryImplementorMock);
|
|
||||||
assertEquals( C0nst4nts३.ABC_DEF, value );
|
|
||||||
verify(classLoaderServiceMock, times(1)).classForName( eq("org.hibernate.orm.test.internal.util.hib3rnat3.C0nst4nts३") );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_getMethod_nestedInterfaces() {
|
public void test_getMethod_nestedInterfaces() {
|
||||||
assertNotNull( ReflectHelper.findGetterMethod( C.class, "id" ) );
|
assertNotNull( ReflectHelper.findGetterMethod( C.class, "id" ) );
|
||||||
|
@ -231,15 +155,4 @@ public class ReflectHelperTest {
|
||||||
public void test_setMethod_nestedInterfaces_on_superclasses() {
|
public void test_setMethod_nestedInterfaces_on_superclasses() {
|
||||||
assertNotNull( ReflectHelper.findSetterMethod( E.class, "id", String.class ) );
|
assertNotNull( ReflectHelper.findSetterMethod( E.class, "id", String.class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestForIssue(jiraKey = "HHH-14059")
|
|
||||||
@Test
|
|
||||||
public void test_getConstantValue_UpperCaseEnum() {
|
|
||||||
when( sessionFactoryOptionsMock.isConventionalJavaConstants() ).thenReturn( true );
|
|
||||||
|
|
||||||
when( classLoaderServiceMock.classForName( "com.example.UStatus" ) ).thenReturn( (Class) Status.class );
|
|
||||||
Object value = ReflectHelper.getConstantValue( "com.example.UStatus.OFF", sessionFactoryImplementorMock);
|
|
||||||
assertEquals( OFF, value );
|
|
||||||
verify(classLoaderServiceMock, times(1)).classForName( eq("com.example.UStatus") );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue