HHH-16028 allow FunctionContributor to be registered programmatically
since we can do this with its friend TypeContributor
This commit is contained in:
parent
2e84d51838
commit
a3b2e9b4ae
|
@ -10,6 +10,7 @@ import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
|
|||
import org.hibernate.boot.archive.scan.spi.ScanOptions;
|
||||
import org.hibernate.boot.archive.scan.spi.Scanner;
|
||||
import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.boot.model.FunctionContributor;
|
||||
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
|
||||
import org.hibernate.boot.model.TypeContributor;
|
||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||
|
@ -369,6 +370,16 @@ public interface MetadataBuilder {
|
|||
@Deprecated(since = "6", forRemoval = true)
|
||||
MetadataBuilder applySourceProcessOrdering(MetadataSourceType... sourceTypes);
|
||||
|
||||
/**
|
||||
* Apply an explicit {@link FunctionContributor}
|
||||
* (implicit application via {@link java.util.ServiceLoader} will still happen too)
|
||||
*
|
||||
* @param functionContributor The contributor to apply
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
MetadataBuilder applyFunctions(FunctionContributor functionContributor);
|
||||
|
||||
/**
|
||||
* Contribute a {@link SqmFunctionDescriptor} to HQL.
|
||||
*
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.hibernate.jpa.spi.MutableJpaCompliance;
|
|||
import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard;
|
||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -55,6 +56,7 @@ public class BootstrapContextImpl implements BootstrapContext {
|
|||
private final MetadataBuildingOptions metadataBuildingOptions;
|
||||
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
private final SqmFunctionRegistry sqmFunctionRegistry;
|
||||
private final MutableJpaCompliance jpaCompliance;
|
||||
|
||||
private final ClassLoaderAccessImpl classLoaderAccess;
|
||||
|
@ -108,6 +110,7 @@ public class BootstrapContextImpl implements BootstrapContext {
|
|||
|
||||
this.typeConfiguration = new TypeConfiguration();
|
||||
this.beanInstanceProducer = new TypeBeanInstanceProducer( configService );
|
||||
this.sqmFunctionRegistry = new SqmFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -125,6 +128,11 @@ public class BootstrapContextImpl implements BootstrapContext {
|
|||
return typeConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return sqmFunctionRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanInstanceProducer getCustomTypeProducer() {
|
||||
return beanInstanceProducer;
|
||||
|
|
|
@ -104,6 +104,7 @@ import org.hibernate.metamodel.CollectionClassification;
|
|||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.query.named.NamedObjectRepository;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -216,6 +217,11 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
|
|||
return bootstrapContext.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return bootstrapContext.getFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Database getDatabase() {
|
||||
// important to delay this instantiation until as late as possible.
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
|
|||
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
||||
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
|
||||
import org.hibernate.boot.cfgxml.spi.MappingReference;
|
||||
import org.hibernate.boot.model.FunctionContributions;
|
||||
import org.hibernate.boot.model.FunctionContributor;
|
||||
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.boot.model.TypeContributor;
|
||||
|
@ -72,6 +74,7 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.spi.ServiceException;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
@ -345,6 +348,27 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyFunctions(FunctionContributor functionContributor) {
|
||||
functionContributor.contributeFunctions( new FunctionContributions() {
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return bootstrapContext.getFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return bootstrapContext.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return bootstrapContext.getServiceRegistry();
|
||||
}
|
||||
} );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applySqlFunction(String functionName, SqmFunctionDescriptor function) {
|
||||
this.bootstrapContext.addSqlFunction( functionName, function );
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.hibernate.query.internal.NamedObjectRepositoryImpl;
|
|||
import org.hibernate.query.named.NamedObjectRepository;
|
||||
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
@ -155,6 +156,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
|||
return bootstrapContext.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return bootstrapContext.getFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryBuilder getSessionFactoryBuilder() {
|
||||
final SessionFactoryBuilderService factoryBuilderService = metadataBuildingOptions.getServiceRegistry().getService( SessionFactoryBuilderService.class );
|
||||
|
|
|
@ -15,18 +15,19 @@
|
|||
package org.hibernate.boot.model;
|
||||
|
||||
/**
|
||||
* On object that contributes custom types and type descriptors, eventually
|
||||
* to a {@link org.hibernate.query.sqm.function.SqmFunctionRegistry}, via an
|
||||
* On object that contributes custom HQL functions, eventually to a
|
||||
* {@link org.hibernate.query.sqm.function.SqmFunctionRegistry}, via an
|
||||
* instance of {@link FunctionContributions}.
|
||||
* <p>
|
||||
* The most common way to integrate a {@code FunctionContributor} is by making
|
||||
* it discoverable via the Java {@link java.util.ServiceLoader} facility.
|
||||
*
|
||||
* @apiNote Unfortunately there's currently no programmatic way to register
|
||||
* an instance with {@code Configuration} or {@code MetadataBuilder}.
|
||||
* Nor can it be registered via a corresponding setting defined in
|
||||
* {@link org.hibernate.jpa.boot.spi.JpaSettings}. These are things
|
||||
* which <em>are</em> possible for its best friend {@link TypeContributor}.
|
||||
* <ul>
|
||||
* <li>
|
||||
* The most common way to integrate a {@code FunctionContributor} is by
|
||||
* making it discoverable via the Java {@link java.util.ServiceLoader}
|
||||
* facility.
|
||||
* <li>
|
||||
* Alternatively, a {@code FunctionContributor} may be programmatically supplied to
|
||||
* {@link org.hibernate.cfg.Configuration#registerFunctionContributor(FunctionContributor)}
|
||||
* or even {@link org.hibernate.boot.MetadataBuilder#applyFunctions(FunctionContributor)}.
|
||||
* </ul>
|
||||
*
|
||||
* @see org.hibernate.query.sqm.function.SqmFunctionRegistry
|
||||
*
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.mapping.PersistentClass;
|
|||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.query.named.NamedObjectRepository;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
|
@ -213,6 +214,11 @@ public abstract class AbstractDelegatingMetadata implements MetadataImplementor
|
|||
return delegate.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return delegate.getFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orderColumns(boolean forceOrdering) {
|
||||
delegate.orderColumns( false );
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
|
|||
import org.hibernate.boot.archive.scan.spi.ScanOptions;
|
||||
import org.hibernate.boot.archive.scan.spi.Scanner;
|
||||
import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.boot.model.FunctionContributor;
|
||||
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
|
||||
import org.hibernate.boot.model.TypeContributor;
|
||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||
|
@ -196,6 +197,12 @@ public abstract class AbstractDelegatingMetadataBuilderImplementor<T extends Met
|
|||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyFunctions(FunctionContributor functionContributor) {
|
||||
delegate.applyFunctions( functionContributor );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applySqlFunction(String functionName, SqmFunctionDescriptor function) {
|
||||
delegate.applySqlFunction( functionName, function );
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
|||
import org.hibernate.jpa.spi.MutableJpaCompliance;
|
||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -57,6 +58,13 @@ public interface BootstrapContext {
|
|||
*/
|
||||
TypeConfiguration getTypeConfiguration();
|
||||
|
||||
/**
|
||||
* The {@link SqmFunctionRegistry} belonging to this {@code BootstrapContext}.
|
||||
*
|
||||
* @see SqmFunctionRegistry
|
||||
*/
|
||||
SqmFunctionRegistry getFunctionRegistry();
|
||||
|
||||
/**
|
||||
* The {@link BeanInstanceProducer} to use when creating custom type references.
|
||||
*
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.query.named.NamedObjectRepository;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -38,6 +39,11 @@ public interface MetadataImplementor extends Metadata {
|
|||
*/
|
||||
TypeConfiguration getTypeConfiguration();
|
||||
|
||||
/**
|
||||
* Access to the {@link SqmFunctionRegistry} belonging to the {@link BootstrapContext}
|
||||
*/
|
||||
SqmFunctionRegistry getFunctionRegistry();
|
||||
|
||||
NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory);
|
||||
|
||||
@Incubating
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.io.File;
|
|||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -31,6 +30,7 @@ import org.hibernate.boot.MetadataSources;
|
|||
import org.hibernate.boot.SessionFactoryBuilder;
|
||||
import org.hibernate.boot.internal.ClassmateContext;
|
||||
import org.hibernate.boot.jaxb.spi.Binding;
|
||||
import org.hibernate.boot.model.FunctionContributor;
|
||||
import org.hibernate.boot.model.NamedEntityGraphDefinition;
|
||||
import org.hibernate.boot.model.TypeContributor;
|
||||
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
||||
|
@ -66,6 +66,8 @@ import org.hibernate.usertype.UserType;
|
|||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.SharedCacheMode;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
/**
|
||||
* A convenience API making it easier to bootstrap an instance of Hibernate.
|
||||
* <p>
|
||||
|
@ -125,8 +127,6 @@ import jakarta.persistence.SharedCacheMode;
|
|||
public class Configuration {
|
||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( Configuration.class );
|
||||
|
||||
public static final String ARTEFACT_PROCESSING_ORDER = AvailableSettings.ARTIFACT_PROCESSING_ORDER;
|
||||
|
||||
private final BootstrapServiceRegistry bootstrapServiceRegistry;
|
||||
private final MetadataSources metadataSources;
|
||||
private final ClassmateContext classmateContext;
|
||||
|
@ -137,6 +137,7 @@ public class Configuration {
|
|||
private final List<BasicType<?>> basicTypes = new ArrayList<>();
|
||||
private List<UserTypeRegistration> userTypeRegistrations;
|
||||
private final List<TypeContributor> typeContributorRegistrations = new ArrayList<>();
|
||||
private final List<FunctionContributor> functionContributorRegistrations = new ArrayList<>();
|
||||
private Map<String, NamedHqlQueryDefinition> namedQueries;
|
||||
private Map<String, NamedNativeQueryDefinition> namedSqlQueries;
|
||||
private Map<String, NamedProcedureCallDefinition> namedProcedureCallMap;
|
||||
|
@ -160,6 +161,9 @@ public class Configuration {
|
|||
private Properties properties;
|
||||
private SharedCacheMode sharedCacheMode;
|
||||
|
||||
@Deprecated(since = "6", forRemoval = true)
|
||||
public static final String ARTEFACT_PROCESSING_ORDER = AvailableSettings.ARTIFACT_PROCESSING_ORDER;
|
||||
|
||||
/**
|
||||
* Create a new instance, using a default {@link BootstrapServiceRegistry}
|
||||
* and a newly instantiated {@link MetadataSources}.
|
||||
|
@ -406,6 +410,14 @@ public class Configuration {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link FunctionContributor} to this configuration.
|
||||
*/
|
||||
public Configuration registerFunctionContributor(FunctionContributor functionContributor) {
|
||||
functionContributorRegistrations.add( functionContributor );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@linkplain BasicType type} into the type registry,
|
||||
* potentially replacing a previously registered type.
|
||||
|
@ -816,20 +828,20 @@ public class Configuration {
|
|||
metadataBuilder.applySharedCacheMode( sharedCacheMode );
|
||||
}
|
||||
|
||||
if ( !typeContributorRegistrations.isEmpty() ) {
|
||||
for ( TypeContributor typeContributor : typeContributorRegistrations ) {
|
||||
metadataBuilder.applyTypes( typeContributor );
|
||||
}
|
||||
for ( TypeContributor typeContributor : typeContributorRegistrations ) {
|
||||
metadataBuilder.applyTypes( typeContributor );
|
||||
}
|
||||
|
||||
for ( FunctionContributor functionContributor : functionContributorRegistrations ) {
|
||||
metadataBuilder.applyFunctions( functionContributor );
|
||||
}
|
||||
|
||||
if ( userTypeRegistrations != null ) {
|
||||
userTypeRegistrations.forEach( registration -> registration.registerType( metadataBuilder ) );
|
||||
}
|
||||
|
||||
if ( !basicTypes.isEmpty() ) {
|
||||
for ( BasicType<?> basicType : basicTypes ) {
|
||||
metadataBuilder.applyBasicType( basicType );
|
||||
}
|
||||
for ( BasicType<?> basicType : basicTypes ) {
|
||||
metadataBuilder.applyBasicType( basicType );
|
||||
}
|
||||
|
||||
if ( customFunctionDescriptors != null ) {
|
||||
|
@ -1029,9 +1041,7 @@ public class Configuration {
|
|||
}
|
||||
|
||||
public java.util.Collection<NamedEntityGraphDefinition> getNamedEntityGraphs() {
|
||||
return namedEntityGraphMap == null
|
||||
? Collections.emptyList()
|
||||
: namedEntityGraphMap.values();
|
||||
return namedEntityGraphMap == null ? emptyList() : namedEntityGraphMap.values();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ public class QueryEngine {
|
|||
MetadataImplementor metadata,
|
||||
QueryEngineOptions queryEngineOptions,
|
||||
Dialect dialect) {
|
||||
final SqmFunctionRegistry sqmFunctionRegistry = new SqmFunctionRegistry();
|
||||
final SqmFunctionRegistry sqmFunctionRegistry = metadata.getFunctionRegistry();
|
||||
|
||||
queryEngineOptions.getCustomSqlFunctionMap().forEach( sqmFunctionRegistry::register );
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.hibernate.jpa.spi.MutableJpaCompliance;
|
|||
import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard;
|
||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -62,6 +63,11 @@ public class BootstrapContextImpl implements BootstrapContext {
|
|||
return delegate.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return delegate.getFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanInstanceProducer getCustomTypeProducer() {
|
||||
return delegate.getCustomTypeProducer();
|
||||
|
|
Loading…
Reference in New Issue