major refactor to horrible instantiation of QueryEngine
This commit is contained in:
parent
2a999d68d2
commit
9f91f2dbff
|
@ -287,7 +287,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
|
|||
}
|
||||
|
||||
@Override
|
||||
public NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory) {
|
||||
public NamedObjectRepository buildNamedQueryRepository() {
|
||||
throw new UnsupportedOperationException( "#buildNamedQueryRepository should not be called on InFlightMetadataCollector" );
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
|
||||
import static org.hibernate.cfg.AvailableSettings.EVENT_LISTENER_PREFIX;
|
||||
import static org.hibernate.internal.util.StringHelper.splitAtCommas;
|
||||
import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize;
|
||||
|
||||
/**
|
||||
* Container for configuration data collected during binding the metamodel.
|
||||
|
@ -356,12 +357,12 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory) {
|
||||
public NamedObjectRepository buildNamedQueryRepository() {
|
||||
return new NamedObjectRepositoryImpl(
|
||||
CollectionHelper.mapOfSize( namedQueryMap.size() ),
|
||||
CollectionHelper.mapOfSize( namedNativeQueryMap.size() ),
|
||||
CollectionHelper.mapOfSize( namedProcedureCallMap.size() ),
|
||||
CollectionHelper.mapOfSize( sqlResultSetMappingMap.size() )
|
||||
mapOfSize( namedQueryMap.size() ),
|
||||
mapOfSize( namedNativeQueryMap.size() ),
|
||||
mapOfSize( namedProcedureCallMap.size() ),
|
||||
mapOfSize( sqlResultSetMappingMap.size() )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -259,8 +259,8 @@ public abstract class AbstractDelegatingMetadata implements MetadataImplementor
|
|||
}
|
||||
|
||||
@Override
|
||||
public NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory) {
|
||||
return delegate().buildNamedQueryRepository( sessionFactory );
|
||||
public NamedObjectRepository buildNamedQueryRepository() {
|
||||
return delegate().buildNamedQueryRepository();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,7 +46,7 @@ public interface MetadataImplementor extends Metadata {
|
|||
*/
|
||||
SqmFunctionRegistry getFunctionRegistry();
|
||||
|
||||
NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory);
|
||||
NamedObjectRepository buildNamedQueryRepository();
|
||||
|
||||
@Incubating
|
||||
void orderColumns(boolean forceOrdering);
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.internal.BaselineSessionEventsListenerBuilder;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
|
||||
import org.hibernate.query.criteria.ValueHandlingMode;
|
||||
import org.hibernate.query.spi.QueryEngineOptions;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
||||
|
@ -242,10 +241,6 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
|||
|
||||
boolean isFailOnPaginationOverCollectionFetchEnabled();
|
||||
|
||||
default ImmutableEntityUpdateQueryHandlingMode getImmutableEntityUpdateQueryHandlingMode() {
|
||||
return ImmutableEntityUpdateQueryHandlingMode.WARNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default catalog to use in generated SQL when a catalog wasn't specified in the mapping,
|
||||
* neither explicitly nor implicitly (see the concept of implicit catalog in XML mapping).
|
||||
|
|
|
@ -227,7 +227,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
settings = getSettings( options, serviceRegistry );
|
||||
maskOutSensitiveInformation( settings );
|
||||
deprecationCheck( settings );
|
||||
LOG.debugf( "Instantiating SessionFactory with settings: %s", settings);
|
||||
LOG.debugf( "Instantiating SessionFactory with settings: %s", settings );
|
||||
|
||||
sqlStringGenerationContext = createSqlStringGenerationContext( bootMetamodel, options, jdbcServices );
|
||||
|
||||
|
@ -280,7 +280,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
// created, then we can split creation of QueryEngine
|
||||
// and SqmFunctionRegistry, instantiating just the
|
||||
// registry here, and doing the engine later
|
||||
queryEngine = QueryEngineImpl.from( this, bootMetamodel );
|
||||
queryEngine = QueryEngineImpl.from( bootMetamodel, options, this, serviceRegistry, settings, name );
|
||||
|
||||
// create runtime metamodels (mapping and JPA)
|
||||
final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl();
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.query;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
|
||||
/**
|
||||
|
@ -30,7 +29,7 @@ public interface BindableType<J> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Resolve this parameter type to the corresponding SqmExpressible
|
||||
* Resolve this parameter type to the corresponding {@link SqmExpressible}
|
||||
*/
|
||||
SqmExpressible<J> resolveExpressible(SessionFactoryImplementor sessionFactory);
|
||||
SqmExpressible<J> resolveExpressible(BindingContext bindingContext);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.query;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* A context within which a {@link BindableType} can be resolved
|
||||
* to an instance of {@link org.hibernate.query.sqm.SqmExpressible}.
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
* @since 7
|
||||
*/
|
||||
@Incubating
|
||||
public interface BindingContext {
|
||||
TypeConfiguration getTypeConfiguration();
|
||||
JpaMetamodel getJpaMetamodel();
|
||||
MappingMetamodel getMappingMetamodel();
|
||||
}
|
|
@ -13,9 +13,9 @@ import java.time.OffsetTime;
|
|||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeHelper;
|
||||
|
@ -39,9 +39,9 @@ public class BindingTypeHelper {
|
|||
public <T> BindableType<T> resolveTemporalPrecision(
|
||||
TemporalType precision,
|
||||
BindableType<T> declaredParameterType,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
BindingContext bindingContext) {
|
||||
if ( precision != null ) {
|
||||
final SqmExpressible<T> sqmExpressible = declaredParameterType.resolveExpressible( sessionFactory );
|
||||
final SqmExpressible<T> sqmExpressible = declaredParameterType.resolveExpressible(bindingContext);
|
||||
if ( !( JavaTypeHelper.isTemporal( sqmExpressible.getExpressibleJavaType() ) ) ) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot treat non-temporal parameter type with temporal precision"
|
||||
|
@ -50,7 +50,7 @@ public class BindingTypeHelper {
|
|||
|
||||
final TemporalJavaType<T> temporalJtd = (TemporalJavaType<T>) sqmExpressible.getExpressibleJavaType();
|
||||
if ( temporalJtd.getPrecision() != precision ) {
|
||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||
final TypeConfiguration typeConfiguration = bindingContext.getTypeConfiguration();
|
||||
final TemporalJavaType<T> temporalTypeForPrecision;
|
||||
// Special case java.util.Date, because TemporalJavaType#resolveTypeForPrecision doesn't support widening,
|
||||
// since the main purpose of that method is to determine the final java type based on the reflective type
|
||||
|
|
|
@ -10,13 +10,13 @@ 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.jdbc.spi.JdbcServices;
|
||||
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.query.BindingContext;
|
||||
import org.hibernate.query.hql.HqlTranslator;
|
||||
import org.hibernate.query.hql.internal.StandardHqlTranslator;
|
||||
import org.hibernate.query.hql.spi.SqmCreationOptions;
|
||||
|
@ -32,7 +32,7 @@ import org.hibernate.query.sqm.spi.SqmCreationContext;
|
|||
import org.hibernate.query.sqm.sql.SqmTranslatorFactory;
|
||||
import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -40,7 +40,6 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.Comparator.comparingInt;
|
||||
|
||||
|
@ -54,23 +53,31 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
|
||||
private static final Logger LOG_HQL_FUNCTIONS = CoreLogging.logger("org.hibernate.HQL_FUNCTIONS");
|
||||
|
||||
public static QueryEngine from(SessionFactoryImplementor sessionFactory, MetadataImplementor metadata) {
|
||||
final QueryEngineOptions options = sessionFactory.getSessionFactoryOptions();
|
||||
final Dialect dialect = sessionFactory.getJdbcServices().getDialect();
|
||||
public static QueryEngineImpl from(
|
||||
MetadataImplementor metadata,
|
||||
QueryEngineOptions options,
|
||||
SqmCreationContext sqmCreationContext,
|
||||
ServiceRegistryImplementor serviceRegistry,
|
||||
Map<String,Object> properties,
|
||||
String name) {
|
||||
final Dialect dialect = serviceRegistry.requireService( JdbcServices.class ).getDialect();
|
||||
return new QueryEngineImpl(
|
||||
sessionFactory,
|
||||
metadata.getTypeConfiguration(),
|
||||
resolveHqlTranslator( options, dialect, sessionFactory, new SqmCreationOptionsStandard( options ) ),
|
||||
resolveHqlTranslator( options, dialect, sqmCreationContext, new SqmCreationOptionsStandard( options ) ),
|
||||
resolveSqmTranslatorFactory( options, dialect ),
|
||||
createFunctionRegistry( sessionFactory, metadata, options, dialect ),
|
||||
metadata.buildNamedQueryRepository( sessionFactory ),
|
||||
buildInterpretationCache( sessionFactory::getStatistics, sessionFactory.getProperties() ),
|
||||
sessionFactory.getServiceRegistry().getService(NativeQueryInterpreter.class)
|
||||
createFunctionRegistry( serviceRegistry, metadata, options, dialect ),
|
||||
metadata.buildNamedQueryRepository(),
|
||||
buildInterpretationCache( serviceRegistry, properties ),
|
||||
serviceRegistry.getService(NativeQueryInterpreter.class),
|
||||
sqmCreationContext,
|
||||
options,
|
||||
options.getUuid(),
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
private static SqmFunctionRegistry createFunctionRegistry(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
ServiceRegistry serviceRegistry,
|
||||
MetadataImplementor metadata,
|
||||
QueryEngineOptions queryEngineOptions,
|
||||
Dialect dialect) {
|
||||
|
@ -84,21 +91,17 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
}
|
||||
|
||||
//TODO: probably better to turn this back into an anonymous class
|
||||
final FunctionContributions functionContributions = new QueryEngineImpl.FunctionContributionsImpl(
|
||||
sessionFactory.getServiceRegistry(),
|
||||
metadata.getTypeConfiguration(),
|
||||
sqmFunctionRegistry
|
||||
);
|
||||
for ( FunctionContributor contributor : sortedFunctionContributors( sessionFactory.getServiceRegistry() ) ) {
|
||||
final FunctionContributions functionContributions =
|
||||
new FunctionContributionsImpl( serviceRegistry, metadata.getTypeConfiguration(), sqmFunctionRegistry );
|
||||
for ( FunctionContributor contributor : sortedFunctionContributors( serviceRegistry ) ) {
|
||||
contributor.contributeFunctions( functionContributions );
|
||||
}
|
||||
|
||||
dialect.initializeFunctionRegistry( functionContributions );
|
||||
|
||||
if ( LOG_HQL_FUNCTIONS.isDebugEnabled() ) {
|
||||
sqmFunctionRegistry.getFunctionsByName().forEach(
|
||||
entry -> LOG_HQL_FUNCTIONS.debug( entry.getValue().getSignature( entry.getKey() ) )
|
||||
);
|
||||
sqmFunctionRegistry.getFunctionsByName()
|
||||
.forEach( entry -> LOG_HQL_FUNCTIONS.debug( entry.getValue().getSignature( entry.getKey() ) ) );
|
||||
}
|
||||
|
||||
return sqmFunctionRegistry;
|
||||
|
@ -114,14 +117,16 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
private final SqmFunctionRegistry sqmFunctionRegistry;
|
||||
|
||||
private QueryEngineImpl(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
TypeConfiguration typeConfiguration,
|
||||
HqlTranslator hqlTranslator,
|
||||
SqmTranslatorFactory sqmTranslatorFactory,
|
||||
SqmFunctionRegistry functionRegistry,
|
||||
NamedObjectRepository namedObjectRepository,
|
||||
QueryInterpretationCache interpretationCache,
|
||||
NativeQueryInterpreter nativeQueryInterpreter) {
|
||||
NativeQueryInterpreter nativeQueryInterpreter,
|
||||
BindingContext context,
|
||||
QueryEngineOptions options,
|
||||
String uuid, String name) {
|
||||
this.typeConfiguration = typeConfiguration;
|
||||
this.sqmFunctionRegistry = functionRegistry;
|
||||
this.sqmTranslatorFactory = sqmTranslatorFactory;
|
||||
|
@ -129,15 +134,13 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
this.namedObjectRepository = namedObjectRepository;
|
||||
this.interpretationCache = interpretationCache;
|
||||
this.nativeQueryInterpreter = nativeQueryInterpreter;
|
||||
final SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions();
|
||||
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
|
||||
sessionFactory.getUuid(),
|
||||
sessionFactory.getName(),
|
||||
this,
|
||||
sessionFactoryOptions.getJpaCompliance().isJpaQueryComplianceEnabled(),
|
||||
sessionFactoryOptions.getCriteriaValueHandlingMode(),
|
||||
() -> sessionFactory
|
||||
);
|
||||
this.criteriaBuilder = createCriteriaBuilder( context, options, uuid, name );
|
||||
}
|
||||
|
||||
private SqmCriteriaNodeBuilder createCriteriaBuilder(
|
||||
BindingContext context, QueryEngineOptions options,
|
||||
String uuid, String name) {
|
||||
return new SqmCriteriaNodeBuilder( uuid, name, this, options, context );
|
||||
}
|
||||
|
||||
private static HqlTranslator resolveHqlTranslator(
|
||||
|
@ -171,10 +174,10 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
}
|
||||
|
||||
private static List<FunctionContributor> sortedFunctionContributors(ServiceRegistry serviceRegistry) {
|
||||
Collection<FunctionContributor> functionContributors =
|
||||
final Collection<FunctionContributor> functionContributors =
|
||||
serviceRegistry.requireService(ClassLoaderService.class)
|
||||
.loadJavaServices(FunctionContributor.class);
|
||||
List<FunctionContributor> contributors = new ArrayList<>( functionContributors );
|
||||
final List<FunctionContributor> contributors = new ArrayList<>( functionContributors );
|
||||
contributors.sort(
|
||||
comparingInt( FunctionContributor::ordinal )
|
||||
.thenComparing( a -> a.getClass().getCanonicalName() )
|
||||
|
@ -183,8 +186,7 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
}
|
||||
|
||||
private static QueryInterpretationCache buildInterpretationCache(
|
||||
Supplier<StatisticsImplementor> statisticsSupplier,
|
||||
Map<String, Object> properties) {
|
||||
ServiceRegistry serviceRegistry, Map<String, Object> properties) {
|
||||
final boolean explicitUseCache = ConfigurationHelper.getBoolean(
|
||||
AvailableSettings.QUERY_PLAN_CACHE_ENABLED,
|
||||
properties,
|
||||
|
@ -202,11 +204,11 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
? explicitMaxPlanSize
|
||||
: QueryEngine.DEFAULT_QUERY_PLAN_MAX_COUNT;
|
||||
|
||||
return new QueryInterpretationCacheStandardImpl( size, statisticsSupplier );
|
||||
return new QueryInterpretationCacheStandardImpl( size, serviceRegistry );
|
||||
}
|
||||
else {
|
||||
// disabled
|
||||
return new QueryInterpretationCacheDisabledImpl( statisticsSupplier );
|
||||
return new QueryInterpretationCacheDisabledImpl( serviceRegistry );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,5 +301,4 @@ public class QueryEngineImpl implements QueryEngine {
|
|||
return serviceRegistry;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.query.sql.spi.ParameterInterpretation;
|
|||
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
|
@ -27,10 +28,12 @@ import org.hibernate.stat.spi.StatisticsImplementor;
|
|||
*/
|
||||
public class QueryInterpretationCacheDisabledImpl implements QueryInterpretationCache {
|
||||
|
||||
private final Supplier<StatisticsImplementor> statisticsSupplier;
|
||||
private final ServiceRegistry serviceRegistry;
|
||||
|
||||
public QueryInterpretationCacheDisabledImpl(Supplier<StatisticsImplementor> statisticsSupplier) {
|
||||
this.statisticsSupplier = statisticsSupplier;
|
||||
private StatisticsImplementor statistics;
|
||||
|
||||
public QueryInterpretationCacheDisabledImpl(ServiceRegistry serviceRegistry) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,9 +46,16 @@ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretation
|
|||
return 0;
|
||||
}
|
||||
|
||||
private StatisticsImplementor getStatistics() {
|
||||
if ( statistics == null ) {
|
||||
statistics = serviceRegistry.requireService( StatisticsImplementor.class );
|
||||
}
|
||||
return statistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> SelectQueryPlan<R> resolveSelectQueryPlan(Key key, Supplier<SelectQueryPlan<R>> creator) {
|
||||
final StatisticsImplementor statistics = statisticsSupplier.get();
|
||||
final StatisticsImplementor statistics = getStatistics();
|
||||
if ( statistics.isStatisticsEnabled() ) {
|
||||
statistics.queryPlanCacheMiss( key.getQueryString() );
|
||||
}
|
||||
|
@ -64,7 +74,7 @@ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretation
|
|||
@Override
|
||||
public <R> HqlInterpretation<R> resolveHqlInterpretation(
|
||||
String queryString, Class<R> expectedResultType, HqlTranslator translator) {
|
||||
final StatisticsImplementor statistics = statisticsSupplier.get();
|
||||
final StatisticsImplementor statistics = getStatistics();
|
||||
final boolean stats = statistics.isStatisticsEnabled();
|
||||
final long startTime = stats ? System.nanoTime() : 0L;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.query.spi.SimpleHqlInterpretationImpl;
|
|||
import org.hibernate.query.sql.spi.ParameterInterpretation;
|
||||
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -40,17 +41,19 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
|||
*/
|
||||
private final BoundedConcurrentHashMap<Key, QueryPlan> queryPlanCache;
|
||||
|
||||
private final ServiceRegistry serviceRegistry;
|
||||
private final BoundedConcurrentHashMap<Object, HqlInterpretation<?>> hqlInterpretationCache;
|
||||
private final BoundedConcurrentHashMap<String, ParameterInterpretation> nativeQueryParamCache;
|
||||
private final Supplier<StatisticsImplementor> statisticsSupplier;
|
||||
|
||||
public QueryInterpretationCacheStandardImpl(int maxQueryPlanCount, Supplier<StatisticsImplementor> statisticsSupplier) {
|
||||
private StatisticsImplementor statistics;
|
||||
|
||||
public QueryInterpretationCacheStandardImpl(int maxQueryPlanCount, ServiceRegistry serviceRegistry) {
|
||||
log.debugf( "Starting QueryInterpretationCache(%s)", maxQueryPlanCount );
|
||||
|
||||
this.queryPlanCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS );
|
||||
this.hqlInterpretationCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS );
|
||||
this.nativeQueryParamCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS );
|
||||
this.statisticsSupplier = statisticsSupplier;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,12 +66,19 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
|||
return queryPlanCache.size();
|
||||
}
|
||||
|
||||
private StatisticsImplementor getStatistics() {
|
||||
if ( statistics == null ) {
|
||||
statistics = serviceRegistry.requireService( StatisticsImplementor.class );
|
||||
}
|
||||
return statistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> SelectQueryPlan<R> resolveSelectQueryPlan(
|
||||
Key key,
|
||||
Supplier<SelectQueryPlan<R>> creator) {
|
||||
log.tracef( "QueryPlan#getSelectQueryPlan(%s)", key );
|
||||
final StatisticsImplementor statistics = statisticsSupplier.get();
|
||||
final StatisticsImplementor statistics = getStatistics();
|
||||
final boolean stats = statistics.isStatisticsEnabled();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -105,7 +115,7 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
|||
Class<R> expectedResultType,
|
||||
HqlTranslator translator) {
|
||||
log.tracef( "QueryPlan#resolveHqlInterpretation( `%s` )", queryString );
|
||||
final StatisticsImplementor statistics = statisticsSupplier.get();
|
||||
final StatisticsImplementor statistics = getStatistics();
|
||||
|
||||
final Object cacheKey = expectedResultType != null
|
||||
? new HqlInterpretationCacheKey( queryString, expectedResultType )
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.query.spi;
|
|||
import java.util.Map;
|
||||
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
|
||||
import org.hibernate.query.criteria.ValueHandlingMode;
|
||||
import org.hibernate.query.hql.HqlTranslator;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
|
@ -73,9 +74,16 @@ public interface QueryEngineOptions {
|
|||
|
||||
ValueHandlingMode getCriteriaValueHandlingMode();
|
||||
|
||||
default ImmutableEntityUpdateQueryHandlingMode getImmutableEntityUpdateQueryHandlingMode() {
|
||||
return ImmutableEntityUpdateQueryHandlingMode.WARNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.hibernate.cfg.AvailableSettings#PORTABLE_INTEGER_DIVISION
|
||||
*/
|
||||
boolean isPortableIntegerDivisionEnabled();
|
||||
|
||||
String getSessionFactoryName();
|
||||
|
||||
String getUuid();
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import java.util.Calendar;
|
|||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.QueryArgumentException;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
|
@ -28,22 +28,22 @@ public class QueryParameterBindingValidator {
|
|||
private QueryParameterBindingValidator() {
|
||||
}
|
||||
|
||||
public void validate(BindableType<?> paramType, Object bind, SessionFactoryImplementor sessionFactory) {
|
||||
validate( paramType, bind, null, sessionFactory );
|
||||
public void validate(BindableType<?> paramType, Object bind, BindingContext bindingContext) {
|
||||
validate( paramType, bind, null, bindingContext);
|
||||
}
|
||||
|
||||
public void validate(
|
||||
BindableType<?> paramType,
|
||||
Object bind,
|
||||
TemporalType temporalPrecision,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
BindingContext bindingContext) {
|
||||
if ( bind == null || paramType == null ) {
|
||||
// nothing we can check
|
||||
return;
|
||||
}
|
||||
|
||||
final Class<?> parameterJavaType;
|
||||
final SqmExpressible<?> sqmExpressible = paramType.resolveExpressible( sessionFactory );
|
||||
final SqmExpressible<?> sqmExpressible = paramType.resolveExpressible(bindingContext);
|
||||
if ( paramType.getBindableJavaType() != null ) {
|
||||
parameterJavaType = paramType.getBindableJavaType();
|
||||
}
|
||||
|
|
|
@ -17,9 +17,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
|
||||
import org.hibernate.query.NullPrecedence;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.SortDirection;
|
||||
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
||||
import org.hibernate.query.criteria.JpaCoalesce;
|
||||
|
@ -78,7 +80,7 @@ import jakarta.persistence.criteria.Subquery;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface NodeBuilder extends HibernateCriteriaBuilder {
|
||||
public interface NodeBuilder extends HibernateCriteriaBuilder, BindingContext {
|
||||
JpaMetamodel getDomainModel();
|
||||
|
||||
TypeConfiguration getTypeConfiguration();
|
||||
|
@ -1194,5 +1196,7 @@ public interface NodeBuilder extends HibernateCriteriaBuilder {
|
|||
|
||||
BasicType<Character> getCharacterType();
|
||||
|
||||
SessionFactoryImplementor getSessionFactory();
|
||||
JpaCompliance getJpaCompliance();
|
||||
|
||||
ImmutableEntityUpdateQueryHandlingMode getImmutableEntityUpdateQueryHandlingMode();
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public interface SqmExpressible<J> extends BindableType<J> {
|
|||
}
|
||||
|
||||
@Override
|
||||
default SqmExpressible<J> resolveExpressible(SessionFactoryImplementor sessionFactory) {
|
||||
default SqmExpressible<J> resolveExpressible(BindingContext bindingContext) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.query.sqm.internal;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
@ -31,18 +32,17 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.dialect.function.AvgFunction;
|
||||
import org.hibernate.dialect.function.SumReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.DdlTypeHelper;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.SessionFactoryRegistry;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
|
@ -50,7 +50,9 @@ import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
|
|||
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
|
||||
import org.hibernate.query.NullPrecedence;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.SortDirection;
|
||||
|
@ -72,6 +74,7 @@ import org.hibernate.query.criteria.JpaWindow;
|
|||
import org.hibernate.query.criteria.ValueHandlingMode;
|
||||
import org.hibernate.query.criteria.spi.CriteriaBuilderExtension;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.spi.QueryEngineOptions;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.ComparisonOperator;
|
||||
import org.hibernate.query.sqm.FrameKind;
|
||||
|
@ -205,10 +208,11 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
|
||||
private final String uuid;
|
||||
private final String name;
|
||||
private final transient boolean jpaComplianceEnabled;
|
||||
private final transient JpaCompliance jpaCompliance;
|
||||
private final transient QueryEngine queryEngine;
|
||||
private final transient Supplier<SessionFactoryImplementor> sessionFactory;
|
||||
private transient ValueHandlingMode criteriaValueHandlingMode;
|
||||
private final transient ImmutableEntityUpdateQueryHandlingMode immutableEntityUpdateQueryHandlingMode;
|
||||
private final transient BindingContext bindingContext;
|
||||
private transient BasicType<Boolean> booleanType;
|
||||
private transient BasicType<Integer> integerType;
|
||||
private transient BasicType<Long> longType;
|
||||
|
@ -220,15 +224,15 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
public SqmCriteriaNodeBuilder(
|
||||
String uuid, String name,
|
||||
QueryEngine queryEngine,
|
||||
boolean jpaComplianceEnabled,
|
||||
ValueHandlingMode criteriaValueHandlingMode,
|
||||
Supplier<SessionFactoryImplementor> sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
QueryEngineOptions options,
|
||||
BindingContext bindingContext) {
|
||||
this.queryEngine = queryEngine;
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.jpaComplianceEnabled = jpaComplianceEnabled;
|
||||
this.criteriaValueHandlingMode = criteriaValueHandlingMode;
|
||||
this.jpaCompliance = options.getJpaCompliance();
|
||||
this.criteriaValueHandlingMode = options.getCriteriaValueHandlingMode();
|
||||
this.immutableEntityUpdateQueryHandlingMode = options.getImmutableEntityUpdateQueryHandlingMode();
|
||||
this.bindingContext = bindingContext;
|
||||
// load registered criteria builder extensions
|
||||
this.extensions = new HashMap<>();
|
||||
for ( CriteriaBuilderExtension extension : ServiceLoader.load( CriteriaBuilderExtension.class ) ) {
|
||||
|
@ -243,7 +247,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
|
||||
@Override
|
||||
public JpaMetamodel getDomainModel() {
|
||||
return getSessionFactory().getJpaMetamodel();
|
||||
return bindingContext.getJpaMetamodel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -253,14 +257,18 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
|
||||
@Override
|
||||
public boolean isJpaQueryComplianceEnabled() {
|
||||
return jpaComplianceEnabled;
|
||||
return jpaCompliance.isJpaQueryComplianceEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory.get();
|
||||
public JpaCompliance getJpaCompliance() {
|
||||
return jpaCompliance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableEntityUpdateQueryHandlingMode getImmutableEntityUpdateQueryHandlingMode() {
|
||||
return immutableEntityUpdateQueryHandlingMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicType<Boolean> getBooleanType() {
|
||||
|
@ -329,7 +337,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
|
||||
@Override
|
||||
public JpaMetamodelImplementor getJpaMetamodel() {
|
||||
return getSessionFactory().getJpaMetamodel();
|
||||
return (JpaMetamodelImplementor) bindingContext.getJpaMetamodel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -349,8 +357,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
@Override
|
||||
public <T> SqmSelectStatement<T> createQuery(String hql, Class<T> resultClass) {
|
||||
final SqmStatement<T> statement =
|
||||
sessionFactory.get().getQueryEngine().getHqlTranslator()
|
||||
.translate( hql, resultClass );
|
||||
queryEngine.getHqlTranslator().translate( hql, resultClass );
|
||||
if ( statement instanceof SqmSelectStatement ) {
|
||||
return new SqmSelectStatement<>( (SqmSelectStatement<T>) statement );
|
||||
}
|
||||
|
@ -1545,7 +1552,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
@Override
|
||||
public <T> SqmLiteral<T> literal(T value) {
|
||||
if ( value == null ) {
|
||||
if ( jpaComplianceEnabled ) {
|
||||
if ( jpaCompliance.isJpaQueryComplianceEnabled() ) {
|
||||
throw new IllegalArgumentException( "literal value cannot be null" );
|
||||
}
|
||||
return new SqmLiteralNull<>( this );
|
||||
|
@ -1553,13 +1560,14 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
else {
|
||||
final BindableType<? super T> valueParamType = getParameterBindType( value );
|
||||
final SqmExpressible<? super T> sqmExpressible =
|
||||
valueParamType == null ? null : valueParamType.resolveExpressible( getSessionFactory() );
|
||||
valueParamType == null ? null : valueParamType.resolveExpressible( this );
|
||||
return new SqmLiteral<>( value, sqmExpressible, this );
|
||||
}
|
||||
}
|
||||
|
||||
private MappingMetamodelImplementor getMappingMetamodel() {
|
||||
return getSessionFactory().getMappingMetamodel();
|
||||
@Override
|
||||
public MappingMetamodelImplementor getMappingMetamodel() {
|
||||
return (MappingMetamodelImplementor) bindingContext.getMappingMetamodel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2086,7 +2094,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
else {
|
||||
return bindableType.getBindableJavaType().isInstance( value )
|
||||
|| bindableType.resolveExpressible( getSessionFactory() ).getExpressibleJavaType().isInstance( value );
|
||||
|| bindableType.resolveExpressible( this ).getExpressibleJavaType().isInstance( value );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2128,7 +2136,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
return new ValueBindJpaCriteriaParameter<>( bindableType, value, this );
|
||||
}
|
||||
final T coercedValue =
|
||||
bindableType.resolveExpressible( getSessionFactory() ).getExpressibleJavaType()
|
||||
bindableType.resolveExpressible( this ).getExpressibleJavaType()
|
||||
.coerce(value, this::getTypeConfiguration );
|
||||
if ( isInstance( bindableType, coercedValue ) ) {
|
||||
return new ValueBindJpaCriteriaParameter<>( bindableType, coercedValue, this );
|
||||
|
@ -2151,7 +2159,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
DomainType<E> elementType = null;
|
||||
if ( bindableType != null ) {
|
||||
final SqmExpressible<E> sqmExpressible = bindableType.resolveExpressible( getSessionFactory() );
|
||||
final SqmExpressible<E> sqmExpressible = bindableType.resolveExpressible( this );
|
||||
elementType = sqmExpressible.getSqmType();
|
||||
}
|
||||
if ( elementType == null ) {
|
||||
|
@ -2958,6 +2966,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
*
|
||||
* @throws InvalidObjectException Thrown if we could not resolve the factory by uuid/name.
|
||||
*/
|
||||
@Serial
|
||||
private Object readResolve() throws InvalidObjectException {
|
||||
LOG.trace( "Resolving serialized SqmCriteriaNodeBuilder" );
|
||||
return locateSessionFactoryOnDeserialization( uuid, name ).getCriteriaBuilder();
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.function.Function;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.Bindable;
|
||||
|
@ -307,16 +308,14 @@ public class SqmUtil {
|
|||
} while (declaringType.getPersistenceType() != Type.PersistenceType.ENTITY );
|
||||
pathBuilder.insert(0, '.');
|
||||
pathBuilder.insert( 0, attribute.getName() );
|
||||
final EntityPersister entityDescriptor = sqmJoin.nodeBuilder()
|
||||
.getSessionFactory()
|
||||
.getMappingMetamodel()
|
||||
final EntityPersister entityDescriptor =
|
||||
sqmJoin.nodeBuilder().getMappingMetamodel()
|
||||
.getEntityDescriptor( ( (EntityDomainType<?>) declaringType ).getHibernateEntityName() );
|
||||
return (EntityAssociationMapping) entityDescriptor.findByPath( pathBuilder.toString() );
|
||||
}
|
||||
else {
|
||||
final EntityPersister entityDescriptor = sqmJoin.nodeBuilder()
|
||||
.getSessionFactory()
|
||||
.getMappingMetamodel()
|
||||
final EntityPersister entityDescriptor =
|
||||
sqmJoin.nodeBuilder().getMappingMetamodel()
|
||||
.getEntityDescriptor( ( (EntityDomainType<?>) declaringType ).getHibernateEntityName() );
|
||||
return (EntityAssociationMapping) entityDescriptor.findAttributeMapping( attribute.getName() );
|
||||
}
|
||||
|
@ -999,7 +998,7 @@ public class SqmUtil {
|
|||
}
|
||||
|
||||
private static void checkQueryReturnType(SqmQuerySpec<?> querySpec, Class<?> expectedResultClass) {
|
||||
final SessionFactoryImplementor sessionFactory = querySpec.nodeBuilder().getSessionFactory();
|
||||
final JpaCompliance jpaCompliance = querySpec.nodeBuilder().getJpaCompliance();
|
||||
final List<SqmSelection<?>> selections = querySpec.getSelectClause().getSelections();
|
||||
if ( selections == null || selections.isEmpty() ) {
|
||||
// make sure there is at least one root
|
||||
|
@ -1009,7 +1008,7 @@ public class SqmUtil {
|
|||
}
|
||||
// if there is a single root, use that as the selection
|
||||
if ( sqmRoots.size() == 1 ) {
|
||||
verifySingularSelectionType( expectedResultClass, sessionFactory, sqmRoots.get( 0 ) );
|
||||
verifySingularSelectionType( expectedResultClass, jpaCompliance, sqmRoots.get( 0 ) );
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException( "Criteria has multiple query roots" );
|
||||
|
@ -1023,17 +1022,17 @@ public class SqmUtil {
|
|||
? expectedResultClass.getComponentType()
|
||||
: expectedResultClass;
|
||||
for ( JpaSelection<?> selection : selectableNode.getSelectionItems() ) {
|
||||
verifySelectionType( expectedSelectItemType, sessionFactory, (SqmSelectableNode<?>) selection );
|
||||
verifySelectionType( expectedSelectItemType, jpaCompliance, (SqmSelectableNode<?>) selection );
|
||||
}
|
||||
}
|
||||
else {
|
||||
verifySingularSelectionType( expectedResultClass, sessionFactory, sqmSelection.getSelectableNode() );
|
||||
verifySingularSelectionType( expectedResultClass, jpaCompliance, sqmSelection.getSelectableNode() );
|
||||
}
|
||||
}
|
||||
else if ( expectedResultClass.isArray() ) {
|
||||
final Class<?> componentType = expectedResultClass.getComponentType();
|
||||
for ( SqmSelection<?> selection : selections ) {
|
||||
verifySelectionType( componentType, sessionFactory, selection.getSelectableNode() );
|
||||
verifySelectionType( componentType, jpaCompliance, selection.getSelectableNode() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1050,10 +1049,10 @@ public class SqmUtil {
|
|||
*/
|
||||
private static void verifySingularSelectionType(
|
||||
Class<?> expectedResultClass,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
JpaCompliance jpaCompliance,
|
||||
SqmSelectableNode<?> selectableNode) {
|
||||
try {
|
||||
verifySelectionType( expectedResultClass, sessionFactory, selectableNode );
|
||||
verifySelectionType( expectedResultClass, jpaCompliance, selectableNode );
|
||||
}
|
||||
catch (QueryTypeMismatchException mismatchException) {
|
||||
// Check for special case of a single selection item and implicit instantiation.
|
||||
|
@ -1084,7 +1083,7 @@ public class SqmUtil {
|
|||
|
||||
private static <T> void verifySelectionType(
|
||||
Class<T> expectedResultClass,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
JpaCompliance jpaCompliance,
|
||||
SqmSelectableNode<?> selection) {
|
||||
// special case for parameters in the select list
|
||||
if ( selection instanceof SqmParameter ) {
|
||||
|
@ -1097,7 +1096,7 @@ public class SqmUtil {
|
|||
}
|
||||
}
|
||||
|
||||
if ( !sessionFactory.getSessionFactoryOptions().getJpaCompliance().isJpaQueryComplianceEnabled() ) {
|
||||
if ( !jpaCompliance.isJpaQueryComplianceEnabled() ) {
|
||||
verifyResultType( expectedResultClass, selection.getExpressible() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.query.sqm.internal;
|
|||
|
||||
import jakarta.persistence.criteria.Expression;
|
||||
import jakarta.persistence.metamodel.EntityType;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
|
@ -16,6 +15,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
|||
import org.hibernate.metamodel.model.domain.TupleType;
|
||||
import org.hibernate.metamodel.model.domain.internal.EntityDiscriminatorSqmPathSource;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
|
@ -29,7 +29,6 @@ import org.hibernate.query.sqm.tree.expression.SqmLiteralNull;
|
|||
import org.hibernate.type.BasicPluralType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.QueryParameterJavaObjectType;
|
||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
||||
import java.time.temporal.Temporal;
|
||||
|
@ -77,8 +76,8 @@ import static org.hibernate.type.descriptor.java.JavaTypeHelper.isUnknown;
|
|||
* function application) is legal only when the entity types belong to the same mapped
|
||||
* entity hierarchy.
|
||||
*
|
||||
* @see #assertComparable(Expression, Expression, SessionFactoryImplementor)
|
||||
* @see #assertAssignable(String, SqmPath, SqmTypedNode, SessionFactoryImplementor)
|
||||
* @see #assertComparable(Expression, Expression, BindingContext)
|
||||
* @see #assertAssignable(String, SqmPath, SqmTypedNode, BindingContext)
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -100,12 +99,12 @@ public class TypecheckUtil {
|
|||
* @param lhsType the type of the expression on the LHS of the comparison operator
|
||||
* @param rhsType the type of the expression on the RHS of the comparison operator
|
||||
*
|
||||
* @see #isTypeAssignable(SqmPathSource, SqmExpressible, SessionFactoryImplementor)
|
||||
* @see #isTypeAssignable(SqmPathSource, SqmExpressible, BindingContext)
|
||||
*/
|
||||
public static boolean areTypesComparable(
|
||||
SqmExpressible<?> lhsType,
|
||||
SqmExpressible<?> rhsType,
|
||||
SessionFactoryImplementor factory) {
|
||||
BindingContext bindingContext) {
|
||||
if ( lhsType == null || rhsType == null || lhsType == rhsType ) {
|
||||
return true;
|
||||
}
|
||||
|
@ -139,7 +138,7 @@ public class TypecheckUtil {
|
|||
// for tuple constructors, we must check each element
|
||||
|
||||
if ( lhsDomainType instanceof TupleType && rhsDomainType instanceof TupleType ) {
|
||||
return areTupleTypesComparable( factory, (TupleType<?>) lhsDomainType, (TupleType<?>) rhsDomainType );
|
||||
return areTupleTypesComparable(bindingContext, (TupleType<?>) lhsDomainType, (TupleType<?>) rhsDomainType );
|
||||
}
|
||||
|
||||
// allow comparing an embeddable against a tuple literal
|
||||
|
@ -153,17 +152,17 @@ public class TypecheckUtil {
|
|||
// entities can be compared if they belong to the same inheritance hierarchy
|
||||
|
||||
if ( lhsDomainType instanceof EntityType && rhsDomainType instanceof EntityType ) {
|
||||
return areEntityTypesComparable( (EntityType<?>) lhsDomainType, (EntityType<?>) rhsDomainType, factory );
|
||||
return areEntityTypesComparable( (EntityType<?>) lhsDomainType, (EntityType<?>) rhsDomainType, bindingContext);
|
||||
}
|
||||
|
||||
// entities can be compared to discriminators if they belong to
|
||||
// the same inheritance hierarchy
|
||||
|
||||
if ( lhsDomainType instanceof EntityDiscriminatorSqmPathSource ) {
|
||||
return isDiscriminatorTypeComparable( (EntityDiscriminatorSqmPathSource<?>) lhsDomainType, rhsDomainType, factory );
|
||||
return isDiscriminatorTypeComparable( (EntityDiscriminatorSqmPathSource<?>) lhsDomainType, rhsDomainType, bindingContext);
|
||||
}
|
||||
if ( rhsDomainType instanceof EntityDiscriminatorSqmPathSource ) {
|
||||
return isDiscriminatorTypeComparable( (EntityDiscriminatorSqmPathSource<?>) rhsDomainType, lhsDomainType, factory );
|
||||
return isDiscriminatorTypeComparable( (EntityDiscriminatorSqmPathSource<?>) rhsDomainType, lhsDomainType, bindingContext);
|
||||
}
|
||||
|
||||
// Treat the expressions as comparable if they belong to the same
|
||||
|
@ -173,7 +172,7 @@ public class TypecheckUtil {
|
|||
// enums, user-defined types, etc.
|
||||
|
||||
if ( lhsDomainType instanceof JdbcMapping && rhsDomainType instanceof JdbcMapping ) {
|
||||
if ( areJdbcMappingsComparable( (JdbcMapping) lhsDomainType, (JdbcMapping) rhsDomainType, factory ) ) {
|
||||
if ( areJdbcMappingsComparable( (JdbcMapping) lhsDomainType, (JdbcMapping) rhsDomainType, bindingContext) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -195,14 +194,14 @@ public class TypecheckUtil {
|
|||
private static boolean areJdbcMappingsComparable(
|
||||
JdbcMapping lhsJdbcMapping,
|
||||
JdbcMapping rhsJdbcMapping,
|
||||
SessionFactoryImplementor factory) {
|
||||
BindingContext bindingContext) {
|
||||
if ( areJdbcTypesComparable( lhsJdbcMapping.getJdbcType(), rhsJdbcMapping.getJdbcType() ) ) {
|
||||
return true;
|
||||
}
|
||||
// converters are implicitly applied to the other side when its domain type is compatible
|
||||
else if ( lhsJdbcMapping.getValueConverter() != null || rhsJdbcMapping.getValueConverter() != null ) {
|
||||
final JdbcMapping lhsDomainMapping = getDomainJdbcType( lhsJdbcMapping, factory );
|
||||
final JdbcMapping rhsDomainMapping = getDomainJdbcType( rhsJdbcMapping, factory );
|
||||
final JdbcMapping lhsDomainMapping = getDomainJdbcType( lhsJdbcMapping, bindingContext);
|
||||
final JdbcMapping rhsDomainMapping = getDomainJdbcType( rhsJdbcMapping, bindingContext);
|
||||
return lhsDomainMapping != null && rhsDomainMapping != null && areJdbcTypesComparable(
|
||||
lhsDomainMapping.getJdbcType(),
|
||||
rhsDomainMapping.getJdbcType()
|
||||
|
@ -220,11 +219,11 @@ public class TypecheckUtil {
|
|||
|| lhsJdbcType.isNumber() && rhsJdbcType.isNumber();
|
||||
}
|
||||
|
||||
private static JdbcMapping getDomainJdbcType(JdbcMapping jdbcMapping, SessionFactoryImplementor factory) {
|
||||
private static JdbcMapping getDomainJdbcType(JdbcMapping jdbcMapping, BindingContext bindingContext) {
|
||||
if ( jdbcMapping.getValueConverter() != null ) {
|
||||
final BasicType<?> basicType = factory.getTypeConfiguration().getBasicTypeForJavaType(
|
||||
jdbcMapping.getValueConverter().getDomainJavaType().getJavaType()
|
||||
);
|
||||
final BasicType<?> basicType =
|
||||
bindingContext.getTypeConfiguration()
|
||||
.getBasicTypeForJavaType( jdbcMapping.getValueConverter().getDomainJavaType().getJavaType() );
|
||||
if ( basicType != null ) {
|
||||
return basicType.getJdbcMapping();
|
||||
}
|
||||
|
@ -255,7 +254,7 @@ public class TypecheckUtil {
|
|||
}
|
||||
|
||||
private static boolean areTupleTypesComparable(
|
||||
SessionFactoryImplementor factory,
|
||||
BindingContext bindingContext,
|
||||
TupleType<?> lhsTuple,
|
||||
TupleType<?> rhsTuple) {
|
||||
if ( rhsTuple.componentCount() != lhsTuple.componentCount() ) {
|
||||
|
@ -263,7 +262,7 @@ public class TypecheckUtil {
|
|||
}
|
||||
else {
|
||||
for ( int i = 0; i < lhsTuple.componentCount(); i++ ) {
|
||||
if ( !areTypesComparable( lhsTuple.get(i), rhsTuple.get(i), factory ) ) {
|
||||
if ( !areTypesComparable( lhsTuple.get(i), rhsTuple.get(i), bindingContext) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -273,32 +272,32 @@ public class TypecheckUtil {
|
|||
|
||||
private static boolean areEntityTypesComparable(
|
||||
EntityType<?> lhsType, EntityType<?> rhsType,
|
||||
SessionFactoryImplementor factory) {
|
||||
EntityPersister lhsEntity = getEntityDescriptor( factory, lhsType.getName() );
|
||||
EntityPersister rhsEntity = getEntityDescriptor( factory, rhsType.getName() );
|
||||
BindingContext bindingContext) {
|
||||
EntityPersister lhsEntity = getEntityDescriptor(bindingContext, lhsType.getName() );
|
||||
EntityPersister rhsEntity = getEntityDescriptor(bindingContext, rhsType.getName() );
|
||||
return lhsEntity.getRootEntityName().equals( rhsEntity.getRootEntityName() );
|
||||
}
|
||||
|
||||
private static boolean isDiscriminatorTypeComparable(
|
||||
EntityDiscriminatorSqmPathSource<?> lhsDiscriminator, SqmExpressible<?> rhsType,
|
||||
SessionFactoryImplementor factory) {
|
||||
BindingContext bindingContext) {
|
||||
String entityName = lhsDiscriminator.getEntityDomainType().getHibernateEntityName();
|
||||
EntityPersister lhsEntity = factory.getMappingMetamodel().getEntityDescriptor( entityName );
|
||||
EntityPersister lhsEntity = bindingContext.getMappingMetamodel().getEntityDescriptor( entityName );
|
||||
if ( rhsType instanceof EntityType ) {
|
||||
String rhsEntityName = ((EntityType<?>) rhsType).getName();
|
||||
EntityPersister rhsEntity = getEntityDescriptor( factory, rhsEntityName );
|
||||
EntityPersister rhsEntity = getEntityDescriptor(bindingContext, rhsEntityName );
|
||||
return lhsEntity.getRootEntityName().equals( rhsEntity.getRootEntityName() );
|
||||
}
|
||||
else if ( rhsType instanceof EntityDiscriminatorSqmPathSource ) {
|
||||
EntityDiscriminatorSqmPathSource<?> discriminator = (EntityDiscriminatorSqmPathSource<?>) rhsType;
|
||||
String rhsEntityName = discriminator.getEntityDomainType().getHibernateEntityName();
|
||||
EntityPersister rhsEntity = factory.getMappingMetamodel().getEntityDescriptor( rhsEntityName );
|
||||
EntityPersister rhsEntity = bindingContext.getMappingMetamodel().getEntityDescriptor( rhsEntityName );
|
||||
return rhsEntity.getRootEntityName().equals( lhsEntity.getRootEntityName() );
|
||||
}
|
||||
else {
|
||||
BasicType<?> discriminatorType = (BasicType<?>)
|
||||
lhsDiscriminator.getEntityMapping().getDiscriminatorMapping().getMappedType();
|
||||
return areTypesComparable( discriminatorType, rhsType, factory );
|
||||
return areTypesComparable( discriminatorType, rhsType, bindingContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,11 +305,11 @@ public class TypecheckUtil {
|
|||
* @param targetType the type of the path expression to which a value is assigned
|
||||
* @param expressionType the type of the value expression being assigned to the path
|
||||
*
|
||||
* @see #areTypesComparable(SqmExpressible, SqmExpressible, SessionFactoryImplementor)
|
||||
* @see #areTypesComparable(SqmExpressible, SqmExpressible, BindingContext)
|
||||
*/
|
||||
private static boolean isTypeAssignable(
|
||||
SqmPathSource<?> targetType, SqmExpressible<?> expressionType,
|
||||
SessionFactoryImplementor factory) {
|
||||
BindingContext bindingContext) {
|
||||
|
||||
if ( targetType == null || expressionType == null || targetType == expressionType ) {
|
||||
return true;
|
||||
|
@ -319,7 +318,7 @@ public class TypecheckUtil {
|
|||
// entities can be assigned if they belong to the same inheritance hierarchy
|
||||
|
||||
if ( targetType instanceof EntityType && expressionType instanceof EntityType ) {
|
||||
return isEntityTypeAssignable( (EntityType<?>) targetType, (EntityType<?>) expressionType, factory );
|
||||
return isEntityTypeAssignable( (EntityType<?>) targetType, (EntityType<?>) expressionType, bindingContext);
|
||||
}
|
||||
|
||||
// Treat the expression as assignable to the target path if they belong
|
||||
|
@ -367,21 +366,21 @@ public class TypecheckUtil {
|
|||
|
||||
private static boolean isEntityTypeAssignable(
|
||||
EntityType<?> lhsType, EntityType<?> rhsType,
|
||||
SessionFactoryImplementor factory) {
|
||||
EntityPersister lhsEntity = getEntityDescriptor( factory, lhsType.getName() );
|
||||
EntityPersister rhsEntity = getEntityDescriptor( factory, rhsType.getName() );
|
||||
BindingContext bindingContext) {
|
||||
EntityPersister lhsEntity = getEntityDescriptor(bindingContext, lhsType.getName() );
|
||||
EntityPersister rhsEntity = getEntityDescriptor(bindingContext, rhsType.getName() );
|
||||
return lhsEntity.isSubclassEntityName( rhsEntity.getEntityName() );
|
||||
}
|
||||
|
||||
private static EntityPersister getEntityDescriptor(SessionFactoryImplementor factory, String name) {
|
||||
return factory.getMappingMetamodel()
|
||||
.getEntityDescriptor( factory.getJpaMetamodel().qualifyImportableName( name ) );
|
||||
private static EntityPersister getEntityDescriptor(BindingContext bindingContext, String name) {
|
||||
return bindingContext.getMappingMetamodel()
|
||||
.getEntityDescriptor( bindingContext.getJpaMetamodel().qualifyImportableName( name ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TypecheckUtil#assertAssignable(String, SqmPath, SqmTypedNode, SessionFactoryImplementor)
|
||||
* @see TypecheckUtil#assertAssignable(String, SqmPath, SqmTypedNode, BindingContext)
|
||||
*/
|
||||
public static void assertComparable(Expression<?> x, Expression<?> y, SessionFactoryImplementor factory) {
|
||||
public static void assertComparable(Expression<?> x, Expression<?> y, BindingContext bindingContext) {
|
||||
final SqmExpression<?> left = (SqmExpression<?>) x;
|
||||
final SqmExpression<?> right = (SqmExpression<?>) y;
|
||||
final Integer leftTupleLength = left.getTupleLength();
|
||||
|
@ -401,7 +400,7 @@ public class TypecheckUtil {
|
|||
if ( !( left instanceof SqmLiteralNull ) && !( right instanceof SqmLiteralNull ) ) {
|
||||
final SqmExpressible<?> leftType = left.getExpressible();
|
||||
final SqmExpressible<?> rightType = right.getExpressible();
|
||||
if ( !areTypesComparable( leftType, rightType, factory ) ) {
|
||||
if ( !areTypesComparable( leftType, rightType, bindingContext) ) {
|
||||
throw new SemanticException(
|
||||
String.format(
|
||||
"Cannot compare left expression of type '%s' with right expression of type '%s'",
|
||||
|
@ -414,12 +413,12 @@ public class TypecheckUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TypecheckUtil#assertComparable(Expression, Expression, SessionFactoryImplementor)
|
||||
* @see TypecheckUtil#assertComparable(Expression, Expression, BindingContext)
|
||||
*/
|
||||
public static void assertAssignable(
|
||||
String hqlString,
|
||||
SqmPath<?> targetPath, SqmTypedNode<?> expression,
|
||||
SessionFactoryImplementor factory) {
|
||||
BindingContext bindingContext) {
|
||||
// allow assigning literal null to things
|
||||
if ( expression instanceof SqmLiteralNull ) {
|
||||
// TODO: check that the target path is nullable
|
||||
|
@ -427,7 +426,7 @@ public class TypecheckUtil {
|
|||
else {
|
||||
SqmPathSource<?> targetType = targetPath.getNodeType();
|
||||
SqmExpressible<?> expressionType = expression.getNodeType();
|
||||
if ( !isTypeAssignable( targetType, expressionType, factory ) ) {
|
||||
if ( !isTypeAssignable( targetType, expressionType, bindingContext) ) {
|
||||
throw new SemanticException(
|
||||
String.format(
|
||||
"Cannot assign expression of type '%s' to target path '%s' of type '%s'",
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.sqm.spi;
|
|||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
@ -19,7 +20,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating
|
||||
public interface SqmCreationContext {
|
||||
public interface SqmCreationContext extends BindingContext {
|
||||
/**
|
||||
* Access to the domain model metadata
|
||||
*/
|
||||
|
|
|
@ -6162,7 +6162,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
}
|
||||
}
|
||||
|
||||
final SqmExpressible<?> paramSqmType = paramType.resolveExpressible( creationContext.getSessionFactory() );
|
||||
final SqmExpressible<?> paramSqmType = paramType.resolveExpressible( creationContext );
|
||||
|
||||
if ( paramSqmType instanceof SqmPath ) {
|
||||
final MappingModelExpressible<?> modelPart = determineValueMapping( (SqmPath<?>) paramSqmType );
|
||||
|
|
|
@ -196,7 +196,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
|||
@SuppressWarnings("unchecked")
|
||||
public SqmPath<?> get(String attributeName) {
|
||||
final SqmPathSource<?> subNavigable =
|
||||
getResolvedModel().getSubPathSource( attributeName, nodeBuilder().getSessionFactory().getJpaMetamodel() );
|
||||
getResolvedModel().getSubPathSource( attributeName, nodeBuilder().getJpaMetamodel() );
|
||||
return resolvePath( attributeName, subNavigable );
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class JpaCriteriaParameter<T>
|
|||
if ( type == null ) {
|
||||
return null;
|
||||
}
|
||||
return type.resolveExpressible( nodeBuilder.getSessionFactory() );
|
||||
return type.resolveExpressible( nodeBuilder );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,9 +15,9 @@ import java.time.LocalDateTime;
|
|||
import java.time.LocalTime;
|
||||
import java.time.OffsetTime;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
|
@ -37,26 +37,18 @@ import org.hibernate.usertype.internal.OffsetTimeCompositeUserType;
|
|||
*/
|
||||
public class SqmExpressionHelper {
|
||||
public static <T> SqmExpressible<T> toSqmType(BindableType<T> parameterType, SqmCreationState creationState) {
|
||||
return toSqmType( parameterType, creationState.getCreationContext().getNodeBuilder().getSessionFactory() );
|
||||
return toSqmType( parameterType, creationState.getCreationContext() );
|
||||
}
|
||||
|
||||
public static <T> SqmExpressible<T> toSqmType(BindableType<T> anticipatedType, NodeBuilder nodeBuilder) {
|
||||
return toSqmType( anticipatedType, nodeBuilder.getSessionFactory() );
|
||||
}
|
||||
|
||||
// public static <T> SqmExpressible<T> toSqmType(BindableType<T> anticipatedType, TypeConfiguration typeConfiguration) {
|
||||
// return toSqmType( anticipatedType, typeConfiguration.getSessionFactory() );
|
||||
// }
|
||||
|
||||
public static <T> SqmExpressible<T> toSqmType(BindableType<T> anticipatedType, SessionFactoryImplementor sessionFactory) {
|
||||
public static <T> SqmExpressible<T> toSqmType(
|
||||
BindableType<T> anticipatedType, BindingContext bindingContext) {
|
||||
if ( anticipatedType == null ) {
|
||||
return null;
|
||||
}
|
||||
final SqmExpressible<T> sqmExpressible = anticipatedType.resolveExpressible( sessionFactory );
|
||||
final SqmExpressible<T> sqmExpressible = anticipatedType.resolveExpressible(bindingContext);
|
||||
assert sqmExpressible != null;
|
||||
|
||||
return sqmExpressible;
|
||||
|
||||
}
|
||||
|
||||
public static SqmLiteral<Timestamp> timestampLiteralFrom(String literalText, SqmCreationState creationState) {
|
||||
|
|
|
@ -90,11 +90,11 @@ public abstract class AbstractSqmInsertStatement<T> extends AbstractSqmDmlStatem
|
|||
null
|
||||
);
|
||||
}
|
||||
final SessionFactoryImplementor factory = nodeBuilder().getSessionFactory();
|
||||
|
||||
for ( int i = 0; i < expressionsSize; i++ ) {
|
||||
final SqmTypedNode<?> expression = expressions.get( i );
|
||||
final SqmPath<?> targetPath = insertionTargetPaths.get(i);
|
||||
assertAssignable( null, targetPath, expression, factory );
|
||||
assertAssignable( null, targetPath, expression, nodeBuilder() );
|
||||
// if ( expression.getNodeJavaType() == null ) {
|
||||
// continue;
|
||||
// }
|
||||
|
|
|
@ -83,7 +83,7 @@ public class SqmConflictUpdateAction<T> implements SqmNode, JpaConflictUpdateAct
|
|||
else {
|
||||
expression = (SqmExpression) nodeBuilder().value( value );
|
||||
}
|
||||
assertAssignable( null, sqmPath, expression, nodeBuilder().getSessionFactory() );
|
||||
assertAssignable( null, sqmPath, expression, nodeBuilder() );
|
||||
applyAssignment( sqmPath, expression );
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ public class SqmBetweenPredicate extends AbstractNegatableSqmPredicate {
|
|||
this.lowerBound = lowerBound;
|
||||
this.upperBound = upperBound;
|
||||
|
||||
assertComparable( expression, lowerBound, nodeBuilder.getSessionFactory() );
|
||||
assertComparable( expression, upperBound, nodeBuilder.getSessionFactory() );
|
||||
assertComparable( expression, lowerBound, nodeBuilder );
|
||||
assertComparable( expression, upperBound, nodeBuilder );
|
||||
|
||||
final SqmExpressible<?> expressibleType = QueryHelper.highestPrecedenceType(
|
||||
expression.getExpressible(),
|
||||
|
|
|
@ -43,7 +43,7 @@ public class SqmComparisonPredicate extends AbstractNegatableSqmPredicate {
|
|||
this.rightHandExpression = rightHandExpression;
|
||||
this.operator = operator;
|
||||
|
||||
assertComparable( leftHandExpression, rightHandExpression, nodeBuilder.getSessionFactory() );
|
||||
assertComparable( leftHandExpression, rightHandExpression, nodeBuilder );
|
||||
|
||||
final SqmExpressible<?> expressibleType = QueryHelper.highestPrecedenceType(
|
||||
leftHandExpression.getExpressible(),
|
||||
|
@ -59,7 +59,7 @@ public class SqmComparisonPredicate extends AbstractNegatableSqmPredicate {
|
|||
this.leftHandExpression = affirmativeForm.leftHandExpression;
|
||||
this.rightHandExpression = affirmativeForm.rightHandExpression;
|
||||
this.operator = affirmativeForm.operator;
|
||||
assertComparable( leftHandExpression, rightHandExpression, nodeBuilder().getSessionFactory() );
|
||||
assertComparable( leftHandExpression, rightHandExpression, nodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -136,7 +136,7 @@ public class SqmInListPredicate<T> extends AbstractNegatableSqmPredicate impleme
|
|||
}
|
||||
|
||||
private void implyListElementType(SqmExpression<?> expression) {
|
||||
assertComparable( getTestExpression(), expression, nodeBuilder().getSessionFactory() );
|
||||
assertComparable( getTestExpression(), expression, nodeBuilder() );
|
||||
expression.applyInferableType(
|
||||
QueryHelper.highestPrecedenceType2( getTestExpression().getExpressible(), expression.getExpressible() )
|
||||
);
|
||||
|
|
|
@ -42,7 +42,7 @@ public class SqmInSubQueryPredicate<T> extends AbstractNegatableSqmPredicate imp
|
|||
this.testExpression = testExpression;
|
||||
this.subQueryExpression = subQueryExpression;
|
||||
|
||||
assertComparable( testExpression, subQueryExpression, nodeBuilder.getSessionFactory() );
|
||||
assertComparable( testExpression, subQueryExpression, nodeBuilder );
|
||||
|
||||
final SqmExpressible<?> expressibleType = QueryHelper.highestPrecedenceType2(
|
||||
testExpression.getExpressible(),
|
||||
|
|
|
@ -39,7 +39,7 @@ public class SqmMemberOfPredicate extends AbstractNegatableSqmPredicate {
|
|||
|
||||
final SimpleDomainType<?> simpleDomainType = pluralPath.getReferencedPathSource().getElementType();
|
||||
|
||||
if ( !areTypesComparable(leftHandExpression.getNodeType(), simpleDomainType, nodeBuilder.getSessionFactory()) ) {
|
||||
if ( !areTypesComparable( leftHandExpression.getNodeType(), simpleDomainType, nodeBuilder ) ) {
|
||||
throw new SemanticException(
|
||||
String.format(
|
||||
"Cannot compare left expression of type '%s' with right expression of type '%s'",
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -37,10 +36,8 @@ import org.hibernate.query.sqm.tree.from.SqmRoot;
|
|||
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
|
||||
|
||||
import jakarta.persistence.criteria.Expression;
|
||||
import jakarta.persistence.criteria.ParameterExpression;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Subquery;
|
||||
import jakarta.persistence.metamodel.EntityType;
|
||||
import jakarta.persistence.metamodel.SingularAttribute;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
@ -135,12 +132,11 @@ public class SqmUpdateStatement<T>
|
|||
}
|
||||
|
||||
private void verifyImmutableEntityUpdate(String hql) {
|
||||
final SessionFactoryImplementor factory = nodeBuilder().getSessionFactory();
|
||||
final EntityPersister persister =
|
||||
factory.getMappingMetamodel().getEntityDescriptor( getTarget().getEntityName() );
|
||||
nodeBuilder().getMappingMetamodel().getEntityDescriptor( getTarget().getEntityName() );
|
||||
if ( !persister.isMutable() ) {
|
||||
final ImmutableEntityUpdateQueryHandlingMode mode =
|
||||
factory.getSessionFactoryOptions().getImmutableEntityUpdateQueryHandlingMode();
|
||||
nodeBuilder().getImmutableEntityUpdateQueryHandlingMode();
|
||||
final String querySpaces = Arrays.toString( persister.getQuerySpaces() );
|
||||
switch ( mode ) {
|
||||
case WARNING:
|
||||
|
@ -155,13 +151,12 @@ public class SqmUpdateStatement<T>
|
|||
}
|
||||
|
||||
private void verifyUpdateTypesMatch() {
|
||||
final SessionFactoryImplementor factory = nodeBuilder().getSessionFactory();
|
||||
final List<SqmAssignment<?>> assignments = getSetClause().getAssignments();
|
||||
for ( int i = 0; i < assignments.size(); i++ ) {
|
||||
final SqmAssignment<?> assignment = assignments.get( i );
|
||||
final SqmPath<?> targetPath = assignment.getTargetPath();
|
||||
final SqmExpression<?> expression = assignment.getValue();
|
||||
assertAssignable( null, targetPath, expression, factory );
|
||||
assertAssignable( null, targetPath, expression, nodeBuilder() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +202,7 @@ public class SqmUpdateStatement<T>
|
|||
else {
|
||||
expression = (SqmExpression) nodeBuilder().value( value );
|
||||
}
|
||||
assertAssignable( null, sqmPath, expression, nodeBuilder().getSessionFactory() );
|
||||
assertAssignable( null, sqmPath, expression, nodeBuilder() );
|
||||
applyAssignment( sqmPath, expression );
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.sql.ast.spi;
|
|||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +17,7 @@ import org.hibernate.service.ServiceRegistry;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SqlAstCreationContext {
|
||||
public interface SqlAstCreationContext extends BindingContext {
|
||||
/**
|
||||
* The SessionFactory
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,7 @@ package org.hibernate.type;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
|
@ -83,7 +83,7 @@ public final class BasicTypeReference<T> implements BindableType<T>, Serializabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public SqmExpressible<T> resolveExpressible(SessionFactoryImplementor sessionFactory) {
|
||||
return sessionFactory.getTypeConfiguration().getBasicTypeRegistry().resolve( this );
|
||||
public SqmExpressible<T> resolveExpressible(BindingContext bindingContext) {
|
||||
return bindingContext.getTypeConfiguration().getBasicTypeRegistry().resolve( this );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
|||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
@ -844,8 +845,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public SqmExpressible<?> resolveExpressible(SessionFactoryImplementor sessionFactory) {
|
||||
return sessionFactory.getJpaMetamodel().embeddable( getReturnedClass() );
|
||||
public SqmExpressible<?> resolveExpressible(BindingContext bindingContext) {
|
||||
return bindingContext.getJpaMetamodel().embeddable( getReturnedClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.loader.ast.spi.AfterLoadAction;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
@ -19,6 +20,7 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
|||
import org.hibernate.sql.exec.spi.Callback;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseSessionFactoryFunctionalTest;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -80,6 +82,16 @@ public abstract class BaseSqmUnitTest
|
|||
return sessionFactory().getRuntimeMetamodels().getMappingMetamodel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return sessionFactory().getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaMetamodel getJpaMetamodel() {
|
||||
return sessionFactory().getJpaMetamodel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return sessionFactory().getServiceRegistry();
|
||||
|
|
|
@ -6,8 +6,8 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.query.BindingContext;
|
||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
|
@ -35,7 +35,7 @@ public class ArrayType implements UserType<Array>, BindableType<Array>, BasicVal
|
|||
}
|
||||
|
||||
@Override
|
||||
public SqmExpressible<Array> resolveExpressible(SessionFactoryImplementor sessionFactory) {
|
||||
public SqmExpressible<Array> resolveExpressible(BindingContext bindingContext) {
|
||||
// really a UserType should not implement BindableType
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,6 @@ import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
|||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.query.criteria.ValueHandlingMode;
|
||||
import org.hibernate.query.hql.HqlTranslator;
|
||||
import org.hibernate.query.hql.internal.StandardHqlTranslator;
|
||||
import org.hibernate.query.hql.spi.SqmCreationOptions;
|
||||
|
@ -152,6 +151,8 @@ public abstract class MockSessionFactory
|
|||
private final MetadataImplementor bootModel;
|
||||
private final MetadataContext metadataContext;
|
||||
|
||||
private final NodeBuilder nodeBuilder;
|
||||
|
||||
public MockSessionFactory() {
|
||||
|
||||
serviceRegistry = StandardServiceRegistryImpl.create(
|
||||
|
@ -222,6 +223,8 @@ public abstract class MockSessionFactory
|
|||
functionFactory.hypotheticalOrderedSetAggregates();
|
||||
functionFactory.windowFunctions();
|
||||
typeConfiguration.scope((SessionFactoryImplementor) this);
|
||||
|
||||
nodeBuilder = new SqmCriteriaNodeBuilder("", "", this, this, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -460,7 +463,7 @@ public abstract class MockSessionFactory
|
|||
|
||||
@Override
|
||||
public QueryInterpretationCache getInterpretationCache() {
|
||||
return new QueryInterpretationCacheDisabledImpl(this::getStatistics);
|
||||
return new QueryInterpretationCacheDisabledImpl( serviceRegistry );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -475,14 +478,7 @@ public abstract class MockSessionFactory
|
|||
|
||||
@Override
|
||||
public NodeBuilder getCriteriaBuilder() {
|
||||
return new SqmCriteriaNodeBuilder(
|
||||
"",
|
||||
"",
|
||||
this,
|
||||
false,
|
||||
ValueHandlingMode.INLINE,
|
||||
() -> MockSessionFactory.this
|
||||
);
|
||||
return nodeBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue