Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ subprojects { subProject ->
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// compilation
compileJava.options.encoding = 'UTF-8'

tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

task compile
compile.dependsOn compileJava, processResources, compileTestJava, processTestResources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,18 @@ Should we strictly adhere to JPA Query Language (JPQL) syntax, or more broadly s
Setting this to `true` may cause valid HQL to throw an exception because it violates the JPQL subset.

|`hibernate.query.startup_check` | `true` (default value) or `false` |Should named queries be checked during startup?
|`hibernate.query.conventional_java_constants` | `true` or `false` (default value) |
Setting which indicates whether or not Java constant follow the https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html[Java Naming conventions].

Default is `false`.
Existing applications may want to enable this (set it to `true`) if only conventional Java constants are used.

There is a significant performance improvement by setting `hibernate.query.conventional_java_constants` to `true`, because Hibernate can determine if an alias should be treated as a Java constant by simply checking if the alias follows Java constant conventions.

With `hibernate.query.conventional_java_constants` set to `false`, Hibernate determines if an alias should be treated as a Java constant by attempting to load the alias as a class (an expensive operation); if it fails, then Hibernate treats the alias as a Java constant.

Check out https://hibernate.atlassian.net/browse/HHH-4959[HHH-4959] for more details.

|`hibernate.hql.bulk_id_strategy` | A fully-qualified class name, an instance, or a `Class` object reference |Provide a custom `org.hibernate.hql.spi.id.MultiTableBulkIdStrategy` implementation for handling multi-table bulk HQL operations.
|`hibernate.proc.param_null_passing` | `true` or `false` (default value) |

Expand All @@ -310,7 +322,6 @@ Can reference
* `StatementInspector` instance
* `StatementInspector` implementation {@link Class} reference
* `StatementInspector` implementation class name (fully-qualified class name)

|===================================================================================================================================================================================================================================

[[configurations-batch]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ public static class SessionFactoryOptionsStateStandardImpl implements SessionFac
private Map querySubstitutions;
private boolean strictJpaQueryLanguageCompliance;
private boolean namedQueryStartupCheckingEnabled;
private boolean conventionalJavaConstants;
private final boolean procedureParameterNullPassingEnabled;
private final boolean collectionJoinSubqueryRewriteEnabled;

Expand Down Expand Up @@ -600,6 +601,8 @@ public SessionFactoryOptionsStateStandardImpl(StandardServiceRegistry serviceReg
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, false );
this.procedureParameterNullPassingEnabled = cfgService.getSetting( PROCEDURE_NULL_PARAM_PASSING, BOOLEAN, false );
this.collectionJoinSubqueryRewriteEnabled = cfgService.getSetting( COLLECTION_JOIN_SUBQUERY, BOOLEAN, true );

Expand Down Expand Up @@ -851,6 +854,10 @@ public boolean isNamedQueryStartupCheckingEnabled() {
return namedQueryStartupCheckingEnabled;
}

public boolean isConventionalJavaConstants() {
return conventionalJavaConstants;
}

@Override
public boolean isProcedureParameterNullPassingEnabled() {
return procedureParameterNullPassingEnabled;
Expand Down Expand Up @@ -1132,6 +1139,10 @@ public boolean isNamedQueryStartupCheckingEnabled() {
return options.isNamedQueryStartupCheckingEnabled();
}

public boolean isConventionalJavaConstants() {
return options.isConventionalJavaConstants();
}

@Override
public boolean isProcedureParameterNullPassingEnabled() {
return options.isProcedureParameterNullPassingEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ 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;

Expand Down Expand Up @@ -160,6 +161,7 @@ public SessionFactoryOptionsImpl(SessionFactoryOptionsState state) {
this.querySubstitutions = state.getQuerySubstitutions();
this.strictJpaQueryLanguageCompliance = state.isStrictJpaQueryLanguageCompliance();
this.namedQueryStartupCheckingEnabled = state.isNamedQueryStartupCheckingEnabled();
this.conventionalJavaConstants = state.isConventionalJavaConstants();
this.procedureParameterNullPassingEnabled = state.isProcedureParameterNullPassingEnabled();
this.collectionJoinSubqueryRewriteEnabled = state.isCollectionJoinSubqueryRewriteEnabled();

Expand Down Expand Up @@ -339,6 +341,11 @@ public boolean isNamedQueryStartupCheckingEnabled() {
return namedQueryStartupCheckingEnabled;
}

@Override
public boolean isConventionalJavaConstants() {
return conventionalJavaConstants;
}

@Override
public boolean isProcedureParameterNullPassingEnabled() {
return procedureParameterNullPassingEnabled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public interface SessionFactoryOptionsState {

boolean isNamedQueryStartupCheckingEnabled();

boolean isConventionalJavaConstants();

boolean isProcedureParameterNullPassingEnabled();

boolean isCollectionJoinSubqueryRewriteEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ public boolean isNamedQueryStartupCheckingEnabled() {
return delegate.isNamedQueryStartupCheckingEnabled();
}

@Override
public boolean isConventionalJavaConstants() {
return delegate.isConventionalJavaConstants();
}

@Override
public boolean isProcedureParameterNullPassingEnabled() {
return delegate.isProcedureParameterNullPassingEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ public interface SessionFactoryOptions {

boolean isNamedQueryStartupCheckingEnabled();

boolean isConventionalJavaConstants();

boolean isSecondLevelCacheEnabled();

boolean isQueryCacheEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,24 @@ public interface AvailableSettings {
*/
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 false}. Existing applications may want to enable this (set it to {@code true})
* if only conventional Java constants are used.
* <p/>
* There is a significant performance improvement by setting {@code hibernate.query.conventional_java_constants}
* to {@code true}, because Hibernate can determine if an alias should be treated as a Java constant by simply
* checking if the alias follows Java constant conventions.
* <p/>
* With {@code hibernate.query.conventional_java_constants} set to {@code false}, Hibernate determines if an alias
* should be treated as a Java constant by attempting to load the alias as a class (an expensive operation);
* if it fails, then Hibernate treats the alias as a Java constant.
*
* @since 5.1.11, 5.2
*/
String CONVENTIONAL_JAVA_CONSTANTS = "hibernate.query.conventional_java_constants";

/**
* The {@link org.hibernate.exception.spi.SQLExceptionConverter} to use for converting SQLExceptions
* to Hibernate's JDBCException hierarchy. The default is to use the configured
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.ScrollableResults;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.RowSelection;
Expand Down Expand Up @@ -590,7 +589,6 @@ public static class JavaConstantConverter implements NodeTraverser.VisitationStr
private AST dotRoot;

public JavaConstantConverter(SessionFactoryImplementor factory) {

this.factory = factory;
}

Expand All @@ -612,7 +610,7 @@ public void visit(AST node) {
}
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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.util.Locale;

import org.hibernate.QueryException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.spi.QueryTranslator;
Expand Down Expand Up @@ -39,7 +38,7 @@ public void setText(String s) {
// 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 );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.dialect.Dialect;
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
import org.hibernate.hql.internal.ast.HqlSqlWalker;
import org.hibernate.hql.internal.ast.InvalidPathException;
import org.hibernate.hql.internal.ast.tree.BooleanLiteralNode;
import org.hibernate.hql.internal.ast.tree.DotNode;
import org.hibernate.hql.internal.ast.tree.FromClause;
import org.hibernate.hql.internal.ast.tree.IdentNode;
Expand All @@ -35,7 +33,6 @@

import antlr.SemanticException;
import antlr.collections.AST;
import java.util.Locale;

/**
* A delegate that handles literals and constants for HqlSqlWalker, performing the token replacement functions and
Expand Down Expand Up @@ -109,7 +106,7 @@ public void lookupConstant(DotNode node) throws SemanticException {
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 + "'" );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.internal.JoinSequence;
import org.hibernate.hql.spi.QueryTranslator;
import org.hibernate.internal.util.ReflectHelper;
Expand Down Expand Up @@ -419,7 +418,7 @@ else if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) { //named query
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Locale;
import java.util.regex.Pattern;

import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.type.PrimitiveType;
Expand All @@ -32,6 +34,10 @@
*/
@SuppressWarnings("unchecked")
public final class ReflectHelper {

private static final Pattern JAVA_CONSTANT_PATTERN = Pattern.compile(
"[a-z\\d]+\\.([A-Z]{1}[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];

Expand Down Expand Up @@ -229,9 +235,15 @@ private static Getter getter(Class clazz, String name) throws MappingException {
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 ) {
Expand Down Expand Up @@ -331,7 +343,7 @@ public static Constructor getConstructor(Class clazz, Type[] types) throws Prope
throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );

}

public static Method getMethod(Class clazz, Method method) {
try {
return clazz.getMethod( method.getName(), method.getParameterTypes() );
Expand Down
Loading