HHH-14745 Add ordinal() to avoid non-determinism

This commit is contained in:
Karel Maesen 2021-07-26 15:29:27 +02:00 committed by Christian Beikov
parent 9aba4532cd
commit c0a18ee99e
2 changed files with 27 additions and 5 deletions

View File

@ -30,4 +30,16 @@ public interface FunctionContributor {
* @param serviceRegistry The service registry
*/
void contributeFunctions(FunctionContributions functionContributions, ServiceRegistry serviceRegistry);
/**
* Determines order in which the contributions will be applied (lowest ordinal first).
*
* The range 0-500 is reserved for Hibernate, range 500-1000 for libraries and 1000-Integer.MAX_VALUE for
* user-defined FunctionContributors.
*
* @return the ordinal for this FunctionContributor
*/
default int ordinal(){
return 1000;
}
}

View File

@ -6,6 +6,12 @@
*/
package org.hibernate.query.spi;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import org.hibernate.Incubating;
import org.hibernate.boot.model.FunctionContributor;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
@ -37,9 +43,6 @@ import org.hibernate.service.ServiceRegistry;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.Map;
import java.util.function.Supplier;
import org.jboss.logging.Logger;
/**
@ -129,8 +132,7 @@ public class QueryEngine {
userDefinedRegistry.overlay( sqmFunctionRegistry );
}
for ( FunctionContributor contributor : serviceRegistry.getService( ClassLoaderService.class )
.loadJavaServices( FunctionContributor.class ) ) {
for ( FunctionContributor contributor : sortedFunctionContributors( serviceRegistry ) ) {
contributor.contributeFunctions( sqmFunctionRegistry::register, serviceRegistry );
}
@ -288,6 +290,14 @@ public class QueryEngine {
return new StandardSqmTranslatorFactory();
}
private static List<FunctionContributor> sortedFunctionContributors(ServiceRegistry serviceRegistry) {
List<FunctionContributor> contributors = new ArrayList<>( serviceRegistry.getService( ClassLoaderService.class )
.loadJavaServices( FunctionContributor.class ) );
contributors.sort( Comparator.comparingInt( FunctionContributor::ordinal )
.thenComparing( a -> a.getClass().getCanonicalName() ) );
return contributors;
}
private static QueryInterpretationCache buildInterpretationCache(
Supplier<StatisticsImplementor> statisticsSupplier,
Map properties) {