migrate to accessing QueryParameterBindingTypeResolver via MappingMetamodelImplementor

it's just not elegant to have it as a supertype of SessionFactoryImplementor (so deprecate that)
This commit is contained in:
Gavin 2023-01-04 01:50:18 +01:00 committed by Gavin King
parent 196d7a1b5a
commit 1074891a36
15 changed files with 267 additions and 265 deletions

View File

@ -1029,7 +1029,9 @@ public abstract class Dialect implements ConversionContext {
"cast",
new CastFunction(
this,
queryEngine.getPreferredSqlTypeCodeForBoolean()
queryEngine.getTypeConfiguration()
.getCurrentBaseSqlTypeIndicators()
.getPreferredSqlTypeCodeForBoolean()
)
);

View File

@ -349,12 +349,12 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
return delegate.isOpen();
}
@Override
@Override @Deprecated
public <T> BindableType<? extends T> resolveParameterBindType(T bindValue) {
return delegate.resolveParameterBindType( bindValue );
}
@Override
@Override @Deprecated
public <T> BindableType<T> resolveParameterBindType(Class<T> clazz) {
return delegate.resolveParameterBindType( clazz );
}

View File

@ -25,6 +25,7 @@ import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.BindableType;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryParameterBindingTypeResolver;
@ -47,7 +48,8 @@ import org.hibernate.type.spi.TypeConfiguration;
* @author Steve Ebersole
*/
public interface SessionFactoryImplementor
extends Mapping, SessionFactory, SqmCreationContext, SqlAstCreationContext, QueryParameterBindingTypeResolver {
extends Mapping, SessionFactory, SqmCreationContext, SqlAstCreationContext,
QueryParameterBindingTypeResolver { //deprecated extension, use MappingMetamodel
/**
* Get the UUID for this SessionFactory.
* <p>
@ -205,4 +207,16 @@ public interface SessionFactoryImplementor
*/
String bestGuessEntityName(Object object);
/**
* @deprecated Use {@link #getMappingMetamodel()}.{@link MappingMetamodelImplementor#resolveParameterBindType(Object)}
*/
@Deprecated(since = "6.2", forRemoval = true)
<T> BindableType<? extends T> resolveParameterBindType(T bindValue);
/**
* @deprecated Use {@link #getMappingMetamodel()}.{@link MappingMetamodelImplementor#resolveParameterBindType(Class)}
*/
@Deprecated(since = "6.2", forRemoval = true)
<T> BindableType<T> resolveParameterBindType(Class<T> clazz);
}

View File

@ -0,0 +1,63 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.internal;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.query.BindableType;
import org.hibernate.query.spi.QueryParameterBindingTypeResolver;
import java.io.Serializable;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
/**
* @implNote This code was originally in {@link SessionFactoryImpl}, but has been factored out so that it
* can be shared by {@link org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl},
* which is where it really belongs, IMO. Eventually, we can kill off the subtyping relationship
* between {@link SessionFactoryImpl} and {@link QueryParameterBindingTypeResolver}, and then
* get rid of this class.
*
* @author Gavin King
*
* @since 6.2
*/
public abstract class QueryParameterBindingTypeResolverImpl implements QueryParameterBindingTypeResolver {
@Override
public <T> BindableType<T> resolveParameterBindType(Class<T> javaType) {
return getMappingMetamodel().resolveQueryParameterType( javaType );
}
@Override
public <T> BindableType<? extends T> resolveParameterBindType(T bindValue) {
if ( bindValue == null ) {
// we can't guess
return null;
}
final LazyInitializer lazyInitializer = extractLazyInitializer( bindValue );
final Class<?> clazz = lazyInitializer != null ? lazyInitializer.getPersistentClass() : bindValue.getClass();
// Resolve superclass bindable type if necessary, as we don't register types for e.g. Inet4Address
Class<?> c = clazz;
do {
final BindableType<?> type = resolveParameterBindType( c );
if ( type != null ) {
//noinspection unchecked
return (BindableType<? extends T>) type;
}
c = c.getSuperclass();
}
while ( c != Object.class );
if ( !clazz.isEnum() && Serializable.class.isAssignableFrom( clazz ) ) {
//noinspection unchecked
return (BindableType<? extends T>) resolveParameterBindType( Serializable.class );
}
return null;
}
}

View File

@ -10,7 +10,6 @@ import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
@ -77,7 +76,6 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.internal.RuntimeMetamodelsImpl;
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
@ -89,7 +87,6 @@ import org.hibernate.persister.entity.SessionFactoryBasedWrapperOptions;
import org.hibernate.procedure.spi.ProcedureCallImplementor;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.query.BindableType;
import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.named.NamedQueryMemento;
@ -154,7 +151,7 @@ import static org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode.DEL
* @author Steve Ebersole
* @author Chris Cranford
*/
public class SessionFactoryImpl implements SessionFactoryImplementor {
public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl implements SessionFactoryImplementor {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class );
private final String name;
@ -1118,39 +1115,6 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
return fetchProfiles.get( name );
}
@Override
public <T> BindableType<? extends T> resolveParameterBindType(T bindValue) {
if ( bindValue == null ) {
// we can't guess
return null;
}
final LazyInitializer lazyInitializer = extractLazyInitializer( bindValue );
final Class<?> clazz = lazyInitializer != null ? lazyInitializer.getPersistentClass() : bindValue.getClass();
// Resolve superclass bindable type if necessary, as we don't register types for e.g. Inet4Address
Class<?> c = clazz;
do {
final BindableType<?> type = resolveParameterBindType( c );
if ( type != null ) {
//noinspection unchecked
return (BindableType<? extends T>) type;
}
c = c.getSuperclass();
}
while ( c != Object.class );
if ( !clazz.isEnum() && Serializable.class.isAssignableFrom( clazz ) ) {
//noinspection unchecked
return (BindableType<? extends T>) resolveParameterBindType( Serializable.class );
}
return null;
}
@Override
public <T> BindableType<T> resolveParameterBindType(Class<T> javaType) {
return getRuntimeMetamodels().getMappingMetamodel().resolveQueryParameterType( javaType );
}
/**
* @deprecated use {@link #configuredInterceptor(Interceptor, boolean, SessionFactoryOptions)}
*/

View File

@ -34,6 +34,7 @@ import org.hibernate.graph.RootGraph;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.internal.QueryParameterBindingTypeResolverImpl;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.mapping.Collection;
@ -93,7 +94,8 @@ import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetti
* @author Emmanuel Bernard
* @author Andrea Boriero
*/
public class MappingMetamodelImpl implements MappingMetamodelImplementor, MetamodelImplementor, Serializable {
public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
implements MappingMetamodelImplementor, MetamodelImplementor, Serializable {
// todo : Integrate EntityManagerLogger into CoreMessageLogger
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( MappingMetamodelImpl.class );
@ -361,6 +363,11 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
return typeConfiguration;
}
@Override
public MappingMetamodel getMappingMetamodel() {
return this;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;

View File

@ -11,11 +11,12 @@ import java.util.Set;
import org.hibernate.EntityNameResolver;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.query.spi.QueryParameterBindingTypeResolver;
/**
* @author Steve Ebersole
*/
public interface MappingMetamodelImplementor extends MappingMetamodel {
public interface MappingMetamodelImplementor extends MappingMetamodel, QueryParameterBindingTypeResolver {
/**
* Retrieves a set of all the collection roles in which the given entity is a participant, as either an
@ -33,6 +34,4 @@ public interface MappingMetamodelImplementor extends MappingMetamodel {
*/
Collection<EntityNameResolver> getEntityNameResolvers();
}

View File

@ -488,7 +488,7 @@ public class ProcedureCallImpl<R>
@Override
public <T> ProcedureParameter<T> registerParameter(int position, Class<T> javaType, ParameterMode mode) {
final BindableType<T> parameterType = getSessionFactory().resolveParameterBindType( javaType );
final BindableType<T> parameterType = getSessionFactory().getMappingMetamodel().resolveParameterBindType( javaType );
final ProcedureParameterImpl<T> procedureParameter = new ProcedureParameterImpl<>(
position,
@ -531,7 +531,7 @@ public class ProcedureCallImpl<R>
@Override
public <T> ProcedureParameterImplementor<T> registerParameter(String name, Class<T> javaType, ParameterMode mode) {
final BindableType<T> parameterType = getSessionFactory().resolveParameterBindType( javaType );
final BindableType<T> parameterType = getSessionFactory().getMappingMetamodel().resolveParameterBindType( javaType );
final ProcedureParameterImpl<T> parameter = new ProcedureParameterImpl<>(
name,

View File

@ -174,7 +174,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
if ( bindType == null ) {
if ( value != null ) {
this.bindType = sessionFactory.resolveParameterBindType( value );
this.bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
}
}
}
@ -267,7 +267,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
}
if ( bindType == null && value != null ) {
this.bindType = sessionFactory.resolveParameterBindType( value );
this.bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
}
}

View File

@ -1429,7 +1429,7 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract
type = getParameterMetadata().getQueryParameter( namedParam ).getHibernateType();
}
if ( type == null && retType != null ) {
type = getSession().getFactory().resolveParameterBindType( retType );
type = getSession().getFactory().getMappingMetamodel().resolveParameterBindType( retType );
}
//noinspection unchecked
return (BindableType<Object>) type;

View File

@ -18,6 +18,7 @@ import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.FunctionContributor;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
@ -25,9 +26,7 @@ import org.hibernate.engine.query.spi.NativeQueryInterpreter;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.query.BindableType;
import org.hibernate.query.criteria.ValueHandlingMode;
import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.hql.internal.StandardHqlTranslator;
@ -36,7 +35,6 @@ import org.hibernate.query.internal.QueryInterpretationCacheDisabledImpl;
import org.hibernate.query.internal.QueryInterpretationCacheStandardImpl;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.query.sqm.internal.SqmCreationOptionsStandard;
import org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;
@ -58,7 +56,7 @@ import static java.util.Comparator.comparingInt;
* @author Steve Ebersole
*/
@Incubating
public class QueryEngine implements QueryParameterBindingTypeResolver {
public class QueryEngine {
/**
* The default soft reference count.
@ -68,146 +66,91 @@ public class QueryEngine implements QueryParameterBindingTypeResolver {
private static final Logger LOG_HQL_FUNCTIONS = CoreLogging.logger( "org.hibernate.HQL_FUNCTIONS" );
public static QueryEngine from(SessionFactoryImplementor sessionFactory, MetadataImplementor metadata) {
final QueryEngineOptions queryEngineOptions = sessionFactory.getSessionFactoryOptions();
final QueryEngineOptions options = sessionFactory.getSessionFactoryOptions();
final Dialect dialect = sessionFactory.getJdbcServices().getDialect();
return new QueryEngine(
sessionFactory,
resolveHqlTranslator(
queryEngineOptions,
dialect,
sessionFactory,
new SqmCreationOptionsStandard( queryEngineOptions )
),
resolveSqmTranslatorFactory( queryEngineOptions, dialect ),
metadata,
dialect,
buildCustomFunctionRegistry( queryEngineOptions )
);
}
private static SqmFunctionRegistry buildCustomFunctionRegistry(QueryEngineOptions queryEngineOptions) {
if ( queryEngineOptions.getCustomSqmFunctionRegistry() == null ) {
final Map<String, SqmFunctionDescriptor> customSqlFunctionMap = queryEngineOptions.getCustomSqlFunctionMap();
if ( customSqlFunctionMap == null || customSqlFunctionMap.isEmpty() ) {
return null;
}
else {
SqmFunctionRegistry customSqmFunctionRegistry = new SqmFunctionRegistry();
customSqlFunctionMap.forEach( customSqmFunctionRegistry::register );
return customSqmFunctionRegistry;
}
}
else {
return queryEngineOptions.getCustomSqmFunctionRegistry();
}
}
private final NamedObjectRepository namedObjectRepository;
private final SqmCriteriaNodeBuilder criteriaBuilder;
private final HqlTranslator hqlTranslator;
private final SqmTranslatorFactory sqmTranslatorFactory;
private final NativeQueryInterpreter nativeQueryInterpreter;
private final QueryInterpretationCache interpretationCache;
private final SqmFunctionRegistry sqmFunctionRegistry;
private final TypeConfiguration typeConfiguration;
private final int preferredSqlTypeCodeForBoolean;
private final QueryParameterBindingTypeResolver queryParameterBindingTypeResolver;
private QueryEngine(
SessionFactoryImplementor sessionFactory,
HqlTranslator hqlTranslator,
SqmTranslatorFactory sqmTranslatorFactory,
MetadataImplementor metadata,
Dialect dialect,
SqmFunctionRegistry customFunctionRegistry) {
this(
sessionFactory.getUuid(),
sessionFactory.getName(),
sessionFactory.getSessionFactoryOptions().getJpaCompliance(),
() -> sessionFactory.getRuntimeMetamodels().getJpaMetamodel(),
sessionFactory.getSessionFactoryOptions().getCriteriaValueHandlingMode(),
sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean(),
metadata.buildNamedQueryRepository( sessionFactory ),
hqlTranslator,
sqmTranslatorFactory,
sessionFactory.getServiceRegistry().getService( NativeQueryInterpreter.class ),
buildInterpretationCache( sessionFactory::getStatistics, sessionFactory.getProperties() ),
metadata.getTypeConfiguration(),
dialect,
customFunctionRegistry,
sessionFactory.getServiceRegistry(),
sessionFactory
resolveHqlTranslator( options, dialect, sessionFactory, new SqmCreationOptionsStandard( options ) ),
resolveSqmTranslatorFactory( options, dialect ),
createFunctionRegistry( sessionFactory, metadata, options, dialect ),
metadata.buildNamedQueryRepository( sessionFactory ),
buildInterpretationCache( sessionFactory::getStatistics, sessionFactory.getProperties() )
);
}
private QueryEngine(
String uuid,
String name,
JpaCompliance jpaCompliance,
Supplier<JpaMetamodelImplementor> jpaMetamodelAccess,
ValueHandlingMode criteriaValueHandlingMode,
int preferredSqlTypeCodeForBoolean,
NamedObjectRepository namedObjectRepository,
HqlTranslator hqlTranslator,
SqmTranslatorFactory sqmTranslatorFactory,
NativeQueryInterpreter nativeQueryInterpreter,
QueryInterpretationCache interpretationCache,
TypeConfiguration typeConfiguration,
Dialect dialect,
SqmFunctionRegistry userDefinedRegistry,
ServiceRegistry serviceRegistry,
SessionFactoryImplementor sessionFactory) {
this.queryParameterBindingTypeResolver = sessionFactory;
this.namedObjectRepository = Objects.requireNonNull( namedObjectRepository );
this.sqmTranslatorFactory = sqmTranslatorFactory;
this.nativeQueryInterpreter = Objects.requireNonNull( nativeQueryInterpreter );
this.interpretationCache = interpretationCache;
this.hqlTranslator = hqlTranslator;
private static SqmFunctionRegistry createFunctionRegistry(
SessionFactoryImplementor sessionFactory,
MetadataImplementor metadata,
QueryEngineOptions queryEngineOptions,
Dialect dialect) {
final SqmFunctionRegistry sqmFunctionRegistry = new SqmFunctionRegistry();
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
uuid,
name,
jpaCompliance.isJpaQueryComplianceEnabled(),
this,
jpaMetamodelAccess,
serviceRegistry,
criteriaValueHandlingMode,
sessionFactory
);
queryEngineOptions.getCustomSqlFunctionMap().forEach( sqmFunctionRegistry::register );
this.sqmFunctionRegistry = new SqmFunctionRegistry();
this.typeConfiguration = typeConfiguration;
this.preferredSqlTypeCodeForBoolean = preferredSqlTypeCodeForBoolean;
dialect.initializeFunctionRegistry( this );
if ( userDefinedRegistry != null ) {
userDefinedRegistry.overlay( sqmFunctionRegistry );
final SqmFunctionRegistry customSqmFunctionRegistry = queryEngineOptions.getCustomSqmFunctionRegistry();
if ( customSqmFunctionRegistry != null ) {
customSqmFunctionRegistry.overlay( sqmFunctionRegistry );
}
final FunctionContributions functionContributions = new FunctionContributions() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public SqmFunctionRegistry getFunctionRegistry() {
return sqmFunctionRegistry;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
};
for ( FunctionContributor contributor : sortedFunctionContributors( serviceRegistry ) ) {
//TODO: probably better to turn this back into an anonymous class
final FunctionContributions functionContributions = new FunctionContributionsImpl(
sessionFactory.getServiceRegistry(),
metadata.getTypeConfiguration(),
sqmFunctionRegistry
);
for ( FunctionContributor contributor : sortedFunctionContributors( sessionFactory.getServiceRegistry() ) ) {
contributor.contributeFunctions( functionContributions );
}
// can't move this here just yet!
//dialect.initializeFunctionRegistry( this );
if ( LOG_HQL_FUNCTIONS.isDebugEnabled() ) {
sqmFunctionRegistry.getFunctionsByName().forEach(
entry -> LOG_HQL_FUNCTIONS.debug( entry.getValue().getSignature( entry.getKey() ) )
);
}
return sqmFunctionRegistry;
}
private final NamedObjectRepository namedObjectRepository;
private final NativeQueryInterpreter nativeQueryInterpreter;
private final QueryInterpretationCache interpretationCache;
private final SqmCriteriaNodeBuilder criteriaBuilder;
private final HqlTranslator hqlTranslator;
private final SqmTranslatorFactory sqmTranslatorFactory;
private final SqmFunctionRegistry sqmFunctionRegistry;
private final TypeConfiguration typeConfiguration;
private QueryEngine(
SessionFactoryImplementor sessionFactory,
TypeConfiguration typeConfiguration,
HqlTranslator hqlTranslator,
SqmTranslatorFactory sqmTranslatorFactory,
SqmFunctionRegistry functionRegistry,
NamedObjectRepository namedObjectRepository,
QueryInterpretationCache interpretationCache) {
this.typeConfiguration = typeConfiguration;
this.sqmFunctionRegistry = functionRegistry;
this.sqmTranslatorFactory = sqmTranslatorFactory;
this.hqlTranslator = hqlTranslator;
this.namedObjectRepository = namedObjectRepository;
this.interpretationCache = interpretationCache;
this.nativeQueryInterpreter = sessionFactory.getServiceRegistry().getService( NativeQueryInterpreter.class );
final SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions();
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
sessionFactory.getUuid(),
sessionFactory.getName(),
this,
sessionFactoryOptions.getJpaCompliance().isJpaQueryComplianceEnabled(),
sessionFactoryOptions.getCriteriaValueHandlingMode(),
sessionFactory.getServiceRegistry(),
() -> sessionFactory
);
// TODO: move into createFunctionRegistry()
sessionFactory.getJdbcServices().getDialect().initializeFunctionRegistry( this );
}
/**
@ -227,62 +170,49 @@ public class QueryEngine implements QueryParameterBindingTypeResolver {
this.namedObjectRepository = Objects.requireNonNull( namedObjectRepository );
this.sqmTranslatorFactory = null;
this.nativeQueryInterpreter = Objects.requireNonNull( nativeQueryInterpreter );
this.sqmFunctionRegistry = new SqmFunctionRegistry();
this.typeConfiguration = jpaMetamodel.getTypeConfiguration();
this.preferredSqlTypeCodeForBoolean = preferredSqlTypeCodeForBoolean;
dialect.initializeFunctionRegistry( this );
SessionFactoryImplementor sessionFactory = jpaMetamodel.getTypeConfiguration().getSessionFactory();
this.queryParameterBindingTypeResolver = sessionFactory;
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
uuid,
name,
false,
this,
() -> jpaMetamodel,
serviceRegistry,
criteriaValueHandlingMode,
sessionFactory
);
final SqmCreationContext sqmCreationContext = new SqmCreationContext() {
@Override
public JpaMetamodelImplementor getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
@Override
public QueryEngine getQueryEngine() {
return QueryEngine.this;
}
@Override
public NodeBuilder getNodeBuilder() {
return criteriaBuilder;
}
};
//noinspection Convert2Lambda
this.hqlTranslator = new StandardHqlTranslator(
sqmCreationContext,
new SqmCreationOptions() {
@Override
public boolean useStrictJpaCompliance() {
return useStrictJpaCompliance;
}
}
);
this.interpretationCache = buildInterpretationCache(
() -> serviceRegistry.getService( StatisticsImplementor.class ),
serviceRegistry.getService( ConfigurationService.class ).getSettings()
);
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
uuid,
name,
this,
useStrictJpaCompliance,
criteriaValueHandlingMode,
serviceRegistry,
typeConfiguration::getSessionFactory
);
this.hqlTranslator = new StandardHqlTranslator(
new SqmCreationContext() {
@Override
public JpaMetamodelImplementor getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
@Override
public QueryEngine getQueryEngine() {
return QueryEngine.this;
}
@Override
public NodeBuilder getNodeBuilder() {
return criteriaBuilder;
}
},
() -> useStrictJpaCompliance
);
}
private static HqlTranslator resolveHqlTranslator(
@ -413,17 +343,33 @@ public class QueryEngine implements QueryParameterBindingTypeResolver {
}
}
public int getPreferredSqlTypeCodeForBoolean() {
return preferredSqlTypeCodeForBoolean;
}
private static class FunctionContributionsImpl implements FunctionContributions {
private final ServiceRegistry serviceRegistry;
private final TypeConfiguration typeConfiguration;
private final SqmFunctionRegistry functionRegistry;
@Override
public <T> BindableType<? extends T> resolveParameterBindType(T bindValue) {
return queryParameterBindingTypeResolver.resolveParameterBindType( bindValue );
}
public FunctionContributionsImpl(
ServiceRegistry serviceRegistry,
TypeConfiguration typeConfiguration,
SqmFunctionRegistry functionRegistry) {
this.serviceRegistry = serviceRegistry;
this.typeConfiguration = typeConfiguration;
this.functionRegistry = functionRegistry;
}
@Override
public <T> BindableType<T> resolveParameterBindType(Class<T> clazz) {
return queryParameterBindingTypeResolver.resolveParameterBindType( clazz );
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public SqmFunctionRegistry getFunctionRegistry() {
return functionRegistry;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
}
}

View File

@ -9,6 +9,7 @@ package org.hibernate.query.spi;
import java.util.Map;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.query.criteria.ValueHandlingMode;
import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
@ -69,4 +70,6 @@ public interface QueryEngineOptions {
SqmMultiTableInsertStrategy getCustomSqmMultiTableInsertStrategy();
JpaCompliance getJpaCompliance();
ValueHandlingMode getCriteriaValueHandlingMode();
}

View File

@ -6,12 +6,17 @@
*/
package org.hibernate.query.spi;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.query.BindableType;
import org.hibernate.type.spi.TypeConfiguration;
/**
* A resolver for Type based on a parameter value being bound, when no
* explicit type information is supplied.
* A resolver for {@link BindableType} based on a parameter value being bound, when no explicit type information is
* supplied.
*
* @apiNote This interface was originally a supertype of {@link org.hibernate.engine.spi.SessionFactoryImplementor},
* but this is now a deprecated relationship. Its functionality should now be accessed via its new subtype
* {@link org.hibernate.metamodel.spi.MappingMetamodelImplementor}.
*
* @author Steve Ebersole
*/
@ -19,4 +24,5 @@ public interface QueryParameterBindingTypeResolver {
<T> BindableType<? extends T> resolveParameterBindType(T bindValue);
<T> BindableType<T> resolveParameterBindType(Class<T> clazz);
TypeConfiguration getTypeConfiguration();
MappingMetamodel getMappingMetamodel();
}

View File

@ -43,6 +43,7 @@ import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.query.BindableType;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.SemanticException;
@ -180,35 +181,31 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
private final String name;
private final transient boolean jpaComplianceEnabled;
private final transient QueryEngine queryEngine;
private final transient Supplier<JpaMetamodelImplementor> domainModelAccess;
private final transient ServiceRegistry serviceRegistry;
private final transient Supplier<SessionFactoryImplementor> sessionFactory;
private final transient ValueHandlingMode criteriaValueHandlingMode;
private final transient SessionFactoryImplementor sessionFactory;
private transient BasicType<Boolean> booleanType;
private transient BasicType<Integer> integerType;
private transient BasicType<Character> characterType;
private final transient Map<Class<? extends HibernateCriteriaBuilder>, HibernateCriteriaBuilder> extensions;
public SqmCriteriaNodeBuilder(
String uuid,
String name,
boolean jpaComplianceEnabled,
String uuid, String name,
QueryEngine queryEngine,
Supplier<JpaMetamodelImplementor> domainModelAccess,
ServiceRegistry serviceRegistry,
boolean jpaComplianceEnabled,
ValueHandlingMode criteriaValueHandlingMode,
SessionFactoryImplementor sessionFactory) {
ServiceRegistry serviceRegistry,
Supplier<SessionFactoryImplementor> sessionFactory) {
this.serviceRegistry = serviceRegistry;
this.sessionFactory = sessionFactory;
this.queryEngine = queryEngine;
this.uuid = uuid;
this.name = name;
this.jpaComplianceEnabled = jpaComplianceEnabled;
this.queryEngine = queryEngine;
this.domainModelAccess = domainModelAccess;
this.serviceRegistry = serviceRegistry;
this.criteriaValueHandlingMode = criteriaValueHandlingMode;
// load registered criteria builder extensions
this.extensions = new HashMap<>();
for (CriteriaBuilderExtension extension : ServiceLoader.load( CriteriaBuilderExtension.class ) ) {
for ( CriteriaBuilderExtension extension : ServiceLoader.load( CriteriaBuilderExtension.class ) ) {
HibernateCriteriaBuilder builder = extension.extend( this );
extensions.put( extension.getRegistrationKey(), builder );
}
@ -216,7 +213,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public JpaMetamodel getDomainModel() {
return domainModelAccess.get();
return getSessionFactory().getJpaMetamodel();
}
@Override
@ -231,7 +228,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
return sessionFactory.get();
}
@Override
@ -274,7 +271,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public JpaMetamodelImplementor getJpaMetamodel() {
return domainModelAccess.get();
return getSessionFactory().getJpaMetamodel();
}
public void close() {
@ -621,7 +618,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
expressibleType = (DomainType<R>) typeConfiguration.resolveTupleType( sqmExpressions );
}
else {
expressibleType = domainModelAccess.get().embeddable( tupleType );
expressibleType = getDomainModel().embeddable( tupleType );
}
return tuple( expressibleType, sqmExpressions );
}
@ -1192,14 +1189,18 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return new SqmLiteralNull<>( this );
}
final BindableType<? extends T> valueParamType = queryEngine.resolveParameterBindType( value );
final BindableType<? extends T> valueParamType = getMappingMetamodel().resolveParameterBindType( value );
final SqmExpressible<? extends T> sqmExpressible = valueParamType == null
? null
: valueParamType.resolveExpressible( sessionFactory );
: valueParamType.resolveExpressible( getSessionFactory() );
return new SqmLiteral<>( value, sqmExpressible, this );
}
private MappingMetamodelImplementor getMappingMetamodel() {
return getSessionFactory().getMappingMetamodel();
}
@Override
public <T> List<? extends SqmExpression<T>> literals(T[] values) {
if ( values == null || values.length == 0 ) {
@ -1231,7 +1232,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
final TypeConfiguration typeConfiguration = getTypeConfiguration();
final BasicType<T> basicTypeForJavaType = typeConfiguration.getBasicTypeForJavaType( resultClass );
final SqmExpressible<T> sqmExpressible = basicTypeForJavaType == null
? domainModelAccess.get().managedType( resultClass )
? getDomainModel().managedType( resultClass )
: basicTypeForJavaType;
return new SqmLiteralNull<>(sqmExpressible, this );
}
@ -1240,10 +1241,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
private final JavaType<T> javaType;
public MultiValueParameterType(Class<T> type) {
this.javaType = domainModelAccess.get()
.getTypeConfiguration()
.getJavaTypeRegistry()
.getDescriptor( type );
this.javaType = getTypeConfiguration().getJavaTypeRegistry().getDescriptor( type );
}
@Override
@ -1723,7 +1721,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
this
);
}
final SqmExpressible<T> expressible = bindableType.resolveExpressible( sessionFactory );
final SqmExpressible<T> expressible = bindableType.resolveExpressible( getSessionFactory() );
T coercedValue = expressible.getExpressibleJavaType().coerce( value, this::getTypeConfiguration );
if ( isInstance( bindableType, coercedValue ) ) {
return new ValueBindJpaCriteriaParameter<>(
@ -1735,7 +1733,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
else {
// ignore typeInferenceSource and fallback the value type
return new ValueBindJpaCriteriaParameter<>(
queryEngine.resolveParameterBindType( value ),
getMappingMetamodel().resolveParameterBindType( value ),
value,
this
);
@ -1749,7 +1747,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
if ( bindableType.getBindableJavaType().isInstance( value ) ) {
return true;
}
return bindableType.resolveExpressible( sessionFactory )
return bindableType.resolveExpressible( getSessionFactory() )
.getExpressibleJavaType()
.isInstance( value );
}
@ -1788,7 +1786,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
}
else {
return new ValueBindJpaCriteriaParameter<>(
queryEngine.resolveParameterBindType( value ),
getMappingMetamodel().resolveParameterBindType( value ),
value,
this
);

View File

@ -118,9 +118,9 @@ public abstract class AbstractJdbcParameter
return jdbcMapping;
}
final BindableType<?> parameterType = executionContext.getSession()
.getFactory()
.resolveParameterBindType( bindValue );
final BindableType<?> parameterType =
executionContext.getSession().getFactory().getMappingMetamodel()
.resolveParameterBindType( bindValue );
if ( parameterType instanceof JdbcMapping ) {
return (JdbcMapping) parameterType;
}