From b0ea4aa5e0b6130432f80d60ae3a09f4594a08bf Mon Sep 17 00:00:00 2001 From: lidongy <1879087903@qq.com> Date: Tue, 28 Mar 2023 11:45:45 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-90336=E3=80=90=E6=9D=A5=E6=BA=90?= =?UTF-8?q?=E5=86=85=E6=B5=8BBUG=E3=80=91=E5=B9=B3=E5=8F=B0=E5=B7=A6?= =?UTF-8?q?=E4=BE=A7=E7=9B=AE=E5=BD=95=E6=90=9C=E7=B4=A2=E5=BE=88=E6=85=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boot/internal/SessionFactoryBuilderImpl.java | 12 ++++++++++++ .../boot/internal/SessionFactoryOptionsImpl.java | 9 +++++++++ .../boot/internal/SessionFactoryOptionsState.java | 2 ++ .../spi/AbstractDelegatingSessionFactoryOptions.java | 5 +++++ .../hibernate/boot/spi/SessionFactoryOptions.java | 2 ++ .../third/org/hibernate/cfg/AvailableSettings.java | 11 +++++++++++ .../hql/internal/ast/QueryTranslatorImpl.java | 2 +- .../hql/internal/ast/tree/JavaConstantNode.java | 2 +- .../hql/internal/ast/util/LiteralProcessor.java | 2 +- .../hibernate/hql/internal/classic/WhereParser.java | 2 +- .../org/hibernate/internal/util/ReflectHelper.java | 12 +++++++++++- 11 files changed, 56 insertions(+), 5 deletions(-) diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java index 57a874a82..57a755ef9 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java @@ -483,6 +483,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement private Map querySubstitutions; private boolean strictJpaQueryLanguageCompliance; private boolean namedQueryStartupCheckingEnabled; + private boolean conventionalJavaConstants; private final boolean procedureParameterNullPassingEnabled; private final boolean collectionJoinSubqueryRewriteEnabled; @@ -600,6 +601,8 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement this.querySubstitutions = ConfigurationHelper.toMap( QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", configurationSettings ); this.strictJpaQueryLanguageCompliance = cfgService.getSetting( JPAQL_STRICT_COMPLIANCE, BOOLEAN, false ); this.namedQueryStartupCheckingEnabled = cfgService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true ); + this.conventionalJavaConstants = cfgService.getSetting( + CONVENTIONAL_JAVA_CONSTANTS, BOOLEAN, true ); this.procedureParameterNullPassingEnabled = cfgService.getSetting( PROCEDURE_NULL_PARAM_PASSING, BOOLEAN, false ); this.collectionJoinSubqueryRewriteEnabled = cfgService.getSetting( COLLECTION_JOIN_SUBQUERY, BOOLEAN, true ); @@ -851,6 +854,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement return namedQueryStartupCheckingEnabled; } + @Override + public boolean isConventionalJavaConstants() { + return conventionalJavaConstants; + } + @Override public boolean isProcedureParameterNullPassingEnabled() { return procedureParameterNullPassingEnabled; @@ -1132,6 +1140,10 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement return options.isNamedQueryStartupCheckingEnabled(); } + @Override + public boolean isConventionalJavaConstants() { + return options.isConventionalJavaConstants(); + } @Override public boolean isProcedureParameterNullPassingEnabled() { return options.isProcedureParameterNullPassingEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java index ffaa7a149..f925b5cba 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java @@ -88,6 +88,9 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions { private final Map querySubstitutions; private final boolean strictJpaQueryLanguageCompliance; private final boolean namedQueryStartupCheckingEnabled; + + private final boolean conventionalJavaConstants; + private final boolean procedureParameterNullPassingEnabled; private final boolean collectionJoinSubqueryRewriteEnabled; @@ -160,6 +163,7 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions { this.querySubstitutions = state.getQuerySubstitutions(); this.strictJpaQueryLanguageCompliance = state.isStrictJpaQueryLanguageCompliance(); this.namedQueryStartupCheckingEnabled = state.isNamedQueryStartupCheckingEnabled(); + this.conventionalJavaConstants = state.isConventionalJavaConstants(); this.procedureParameterNullPassingEnabled = state.isProcedureParameterNullPassingEnabled(); this.collectionJoinSubqueryRewriteEnabled = state.isCollectionJoinSubqueryRewriteEnabled(); @@ -339,6 +343,11 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions { return namedQueryStartupCheckingEnabled; } + @Override + public boolean isConventionalJavaConstants() { + return conventionalJavaConstants; + } + @Override public boolean isProcedureParameterNullPassingEnabled() { return procedureParameterNullPassingEnabled; diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java index c73f94f8b..8835f3453 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java @@ -98,6 +98,8 @@ public interface SessionFactoryOptionsState { boolean isNamedQueryStartupCheckingEnabled(); + boolean isConventionalJavaConstants(); + boolean isProcedureParameterNullPassingEnabled(); boolean isCollectionJoinSubqueryRewriteEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java index 3e8a7f603..97d723488 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java @@ -198,6 +198,11 @@ public abstract class AbstractDelegatingSessionFactoryOptions implements Session return delegate.isNamedQueryStartupCheckingEnabled(); } + @Override + public boolean isConventionalJavaConstants() { + return delegate.isConventionalJavaConstants(); + } + @Override public boolean isProcedureParameterNullPassingEnabled() { return delegate.isProcedureParameterNullPassingEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java index 7872aacb7..6c8972464 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java @@ -122,6 +122,8 @@ public interface SessionFactoryOptions { boolean isNamedQueryStartupCheckingEnabled(); + boolean isConventionalJavaConstants(); + boolean isSecondLevelCacheEnabled(); boolean isQueryCacheEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java index 0ac6a9122..80541d2f1 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java @@ -564,6 +564,17 @@ public interface AvailableSettings { */ String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check"; + /** + * Setting which indicates whether or not Java constant follow the Java Naming conventions. + *
+ * Default is {@code true}. Existing applications may want to disable this (set it {@code 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. + * + * @since 5.2 + */ + String CONVENTIONAL_JAVA_CONSTANTS = "hibernate.query.conventional_java_constants"; + /** * The {@link com.fr.third.org.hibernate.exception.spi.SQLExceptionConverter} to use for converting SQLExceptions * to Hibernate's JDBCException hierarchy. The default is to use the configured diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java index e7968fcca..ab9c923a8 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java @@ -612,7 +612,7 @@ public class QueryTranslatorImpl implements FilterTranslator { } private void handleDotStructure(AST dotStructureRoot) { final String expression = ASTUtil.getPathText( dotStructureRoot ); - final Object constant = ReflectHelper.getConstantValue( expression, factory.getServiceRegistry().getService( ClassLoaderService.class ) ); + final Object constant = ReflectHelper.getConstantValue( expression, factory ); if ( constant != null ) { dotStructureRoot.setFirstChild( null ); dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT ); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java index 2f77663fd..5a678968e 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java @@ -39,7 +39,7 @@ public class JavaConstantNode extends Node implements ExpectedTypeAwareNode, Ses // this method to get called twice. The first time with an empty string if ( StringHelper.isNotEmpty( s ) ) { constantExpression = s; - constantValue = ReflectHelper.getConstantValue( s, factory.getServiceRegistry().getService( ClassLoaderService.class ) ); + constantValue = ReflectHelper.getConstantValue( s, factory ); heuristicType = factory.getTypeResolver().heuristicType( constantValue.getClass().getName() ); super.setText( s ); } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java index c414c847f..6fb54838d 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java @@ -107,7 +107,7 @@ public class LiteralProcessor implements HqlSqlTokenTypes { setSQLValue( node, text, discrim ); } else { - Object value = ReflectHelper.getConstantValue( text, walker.getSessionFactoryHelper().getFactory().getServiceRegistry().getService( ClassLoaderService.class ) ); + Object value = ReflectHelper.getConstantValue( text, walker.getSessionFactoryHelper().getFactory() ); if ( value == null ) { throw new InvalidPathException( "Invalid path: '" + text + "'" ); } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java index 618950829..7f22b82ee 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java @@ -419,7 +419,7 @@ public class WhereParser implements Parser { Object constant; if ( token.indexOf( '.' ) > -1 && - ( constant = ReflectHelper.getConstantValue( token, q.getFactory().getServiceRegistry().getService( ClassLoaderService.class ) ) ) != null + ( constant = ReflectHelper.getConstantValue( token, q.getFactory() ) ) != null ) { Type type; try { diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java index bb9d5aa3a..819fc0358 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java @@ -13,12 +13,14 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Locale; +import java.util.regex.Pattern; import com.fr.third.org.hibernate.AssertionFailure; import com.fr.third.org.hibernate.MappingException; import com.fr.third.org.hibernate.PropertyNotFoundException; import com.fr.third.org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import com.fr.third.org.hibernate.boot.registry.classloading.spi.ClassLoadingException; +import com.fr.third.org.hibernate.engine.spi.SessionFactoryImplementor; import com.fr.third.org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl; import com.fr.third.org.hibernate.property.access.spi.Getter; import com.fr.third.org.hibernate.type.PrimitiveType; @@ -32,6 +34,8 @@ import com.fr.third.org.hibernate.type.Type; */ @SuppressWarnings("unchecked") public final class ReflectHelper { + private static final Pattern JAVA_CONSTANT_PATTERN = Pattern.compile( + "[a-z\\d]+\\.([A-Z]+[a-z\\d]+)+\\$?([A-Z]{1}[a-z\\d]+)*\\.[A-Z_\\$]+", Pattern.UNICODE_CHARACTER_CLASS); public static final Class[] NO_PARAM_SIGNATURE = new Class[0]; public static final Object[] NO_PARAMS = new Object[0]; @@ -229,9 +233,15 @@ public final class ReflectHelper { return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess( clazz, name ).getGetter(); } - public static Object getConstantValue(String name, ClassLoaderService classLoaderService) { + 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 ) {