diff --git a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/InformixDialectTestCase.java b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/InformixDialectTestCase.java index a816ab4de9..e3af8f00c1 100644 --- a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/InformixDialectTestCase.java +++ b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/InformixDialectTestCase.java @@ -11,7 +11,7 @@ import java.util.Collections; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl; import org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl; -import org.hibernate.orm.test.jpa.JpaComplianceStub; +import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl; import org.hibernate.query.criteria.ValueHandlingMode; import org.hibernate.query.internal.NamedObjectRepositoryImpl; import org.hibernate.query.spi.QueryEngine; @@ -48,7 +48,8 @@ public class InformixDialectTestCase extends BaseUnitTestCase { @BeforeClass public static void init() { - final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( new TypeConfiguration(), new JpaComplianceStub() ); + TypeConfiguration typeConfiguration = new TypeConfiguration(); + final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl(typeConfiguration, new MappingMetamodelImpl( typeConfiguration, ssr ) ); ssr = new StandardServiceRegistryBuilder().build(); queryEngine = new QueryEngine( diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java index 5c3e868784..363ae0d06b 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityAction.java @@ -13,7 +13,6 @@ import org.hibernate.action.spi.AfterTransactionCompletionProcess; import org.hibernate.action.spi.BeforeTransactionCompletionProcess; import org.hibernate.action.spi.Executable; import org.hibernate.engine.spi.EntityEntry; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.event.spi.EventSource; import org.hibernate.internal.FastSessionServices; import org.hibernate.internal.util.StringHelper; @@ -158,7 +157,7 @@ public abstract class EntityAction return roleComparison != 0 ? roleComparison //then by id - : persister.getIdentifierType().compare( id, action.getId() ); + : persister.getIdentifierType().compare( id, action.getId(), session.getSessionFactory() ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java index d20b98d9c2..e29ece41fa 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java @@ -39,6 +39,7 @@ import org.hibernate.resource.jdbc.spi.StatementInspector; public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplementor { private final MetadataImplementor metadata; private final SessionFactoryOptionsBuilder optionsBuilder; + private final BootstrapContext bootstrapContext; public SessionFactoryBuilderImpl(MetadataImplementor metadata, BootstrapContext bootstrapContext) { this( @@ -46,13 +47,15 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement new SessionFactoryOptionsBuilder( metadata.getMetadataBuildingOptions().getServiceRegistry(), bootstrapContext - ) + ), + bootstrapContext ); } - public SessionFactoryBuilderImpl(MetadataImplementor metadata, SessionFactoryOptionsBuilder optionsBuilder) { + public SessionFactoryBuilderImpl(MetadataImplementor metadata, SessionFactoryOptionsBuilder optionsBuilder, BootstrapContext context) { this.metadata = metadata; this.optionsBuilder = optionsBuilder; + this.bootstrapContext = context; if ( metadata.getSqlFunctionMap() != null ) { for ( Map.Entry sqlFunctionEntry : metadata.getSqlFunctionMap().entrySet() ) { @@ -69,6 +72,14 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement addSessionFactoryObservers( new SessionFactoryObserverForRegistration() ); } + /** + * @deprecated This constructor will be removed + */ + @Deprecated(since = "6.2", forRemoval = true) + public SessionFactoryBuilderImpl(MetadataImplementor metadata, SessionFactoryOptionsBuilder optionsBuilder) { + this( metadata, optionsBuilder, metadata.getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext() ); + } + @Override public SessionFactoryBuilder applyBeanManager(Object beanManager) { this.optionsBuilder.applyBeanManager( beanManager ); @@ -417,7 +428,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement @Override public SessionFactory build() { - return new SessionFactoryImpl( metadata, buildSessionFactoryOptions() ); + return new SessionFactoryImpl( metadata, buildSessionFactoryOptions(), bootstrapContext ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataImplementor.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataImplementor.java index c9024ed9e3..578a03ac84 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataImplementor.java @@ -34,7 +34,7 @@ public interface MetadataImplementor extends Metadata { MetadataBuildingOptions getMetadataBuildingOptions(); /** - * Access to the {@link TypeConfiguration} + * Access to the {@link TypeConfiguration} belonging to the {@link BootstrapContext} */ TypeConfiguration getTypeConfiguration(); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/ChrLiteralEmulation.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/ChrLiteralEmulation.java index 9f5fb677a9..e0f50809f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/ChrLiteralEmulation.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/ChrLiteralEmulation.java @@ -10,11 +10,14 @@ import java.util.List; import java.util.Locale; import org.hibernate.QueryException; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor; import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator; +import org.hibernate.query.sqm.produce.function.ArgumentsValidator; import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators; import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers; import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers; +import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.expression.SqmLiteral; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.spi.SqlAppender; @@ -37,16 +40,19 @@ public class ChrLiteralEmulation extends AbstractSqmSelfRenderingFunctionDescrip "chr", new ArgumentTypesValidator( StandardArgumentsValidators.composite( - StandardArgumentsValidators.exactly( 1 ), - (arguments, functionName, queryEngine) -> { - if ( !( arguments.get( 0 ) instanceof SqmLiteral ) ) { - throw new QueryException( - String.format( - Locale.ROOT, - "Emulation of function chr() supports only integer literals, but %s argument given", - arguments.get( 0 ).getClass().getName() - ) - ); + StandardArgumentsValidators.exactly(1), + new ArgumentsValidator() { + @Override + public void validate(List> arguments, String functionName, MappingMetamodel metamodel) { + if ( !( arguments.get( 0 ) instanceof SqmLiteral ) ) { + throw new QueryException( + String.format( + Locale.ROOT, + "Emulation of function chr() supports only integer literals, but %s argument given", + arguments.get( 0 ).getClass().getName() + ) + ); + } } } ), diff --git a/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java new file mode 100644 index 0000000000..713212356b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java @@ -0,0 +1,80 @@ +/* + * 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 . + */ +package org.hibernate.internal; + +import org.hibernate.HibernateException; +import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.engine.profile.Association; +import org.hibernate.engine.profile.Fetch; +import org.hibernate.engine.profile.FetchProfile; +import org.hibernate.metamodel.MappingMetamodel; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Loadable; +import org.hibernate.type.Type; + +import java.util.HashMap; +import java.util.Map; + +/** + * Creates {@link FetchProfile}s. + * + * @author Gavin King + */ +public class FetchProfileHelper { + + public static Map getFetchProfiles( + MetadataImplementor bootMetamodel, + MappingMetamodel mappingMetamodel) { + final Map fetchProfiles = new HashMap<>(); + for ( org.hibernate.mapping.FetchProfile mappingProfile : bootMetamodel.getFetchProfiles() ) { + final FetchProfile fetchProfile = createFetchProfile( mappingMetamodel, mappingProfile ); + fetchProfiles.put( fetchProfile.getName(), fetchProfile ); + } + return fetchProfiles; + } + + private static FetchProfile createFetchProfile( + MappingMetamodel mappingMetamodel, + org.hibernate.mapping.FetchProfile mappingProfile) { + final FetchProfile fetchProfile = new FetchProfile( mappingProfile.getName() ); + for ( org.hibernate.mapping.FetchProfile.Fetch mappingFetch : mappingProfile.getFetches() ) { + // resolve the persister owning the fetch + final EntityPersister owner = getEntityPersister( mappingMetamodel, fetchProfile, mappingFetch ); + + // validate the specified association fetch + final Type associationType = owner.getPropertyType( mappingFetch.getAssociation() ); + if ( associationType == null || !associationType.isAssociationType() ) { + throw new HibernateException( "Fetch profile [" + fetchProfile.getName() + + "] specified an association that does not exist [" + mappingFetch.getAssociation() + "]" ); + } + + // resolve the style + final Fetch.Style fetchStyle = Fetch.Style.parse( mappingFetch.getStyle() ); + + // then construct the fetch instance... + fetchProfile.addFetch( new Association( owner, mappingFetch.getAssociation() ), fetchStyle ); + ((Loadable) owner).registerAffectingFetchProfile( fetchProfile.getName() ); + } + return fetchProfile; + } + + private static EntityPersister getEntityPersister( + MappingMetamodel mappingMetamodel, + FetchProfile fetchProfile, + org.hibernate.mapping.FetchProfile.Fetch mappingFetch) { + final String entityName = mappingMetamodel.getImportedName( mappingFetch.getEntity() ); + if ( entityName != null ) { + EntityPersister persister = mappingMetamodel.getEntityDescriptor( entityName ); + if ( persister != null ) { + return persister; + } + } + throw new HibernateException( "Unable to resolve entity reference [" + mappingFetch.getEntity() + + "] in fetch profile [" + fetchProfile.getName() + "]" ); + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index ccd91260d6..34db85b6b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -58,8 +58,6 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.profile.Association; -import org.hibernate.engine.profile.Fetch; import org.hibernate.engine.profile.FetchProfile; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.SessionBuilderImplementor; @@ -79,6 +77,7 @@ 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; @@ -86,8 +85,6 @@ import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.MetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.SessionFactoryBasedWrapperOptions; import org.hibernate.procedure.spi.ProcedureCallImplementor; import org.hibernate.proxy.EntityNotFoundDelegate; @@ -132,6 +129,7 @@ import static org.hibernate.cfg.AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLE import static org.hibernate.cfg.AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS; import static org.hibernate.cfg.AvailableSettings.JAKARTA_VALIDATION_FACTORY; import static org.hibernate.cfg.AvailableSettings.JPA_VALIDATION_FACTORY; +import static org.hibernate.internal.FetchProfileHelper.getFetchProfiles; import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean; import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer; import static org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT; @@ -197,11 +195,20 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { private final transient SchemaManager schemaManager; - public SessionFactoryImpl(final MetadataImplementor bootMetamodel, final SessionFactoryOptions options) { - LOG.debug( "Building session factory" ); + /** + * @deprecated This constructor will be removed + */ + @Deprecated(since = "6.2", forRemoval = true) + public SessionFactoryImpl(MetadataImplementor bootMetamodel, SessionFactoryOptions options) { + this( bootMetamodel, options, bootMetamodel.getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext() ); + } - final TypeConfiguration typeConfiguration = bootMetamodel.getTypeConfiguration(); - final BootstrapContext bootstrapContext = typeConfiguration.getMetadataBuildingContext().getBootstrapContext(); + public SessionFactoryImpl( + final MetadataImplementor bootMetamodel, + final SessionFactoryOptions options, + final BootstrapContext bootstrapContext) { + LOG.debug( "Building session factory" ); + final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration(); sessionFactoryOptions = options; @@ -248,15 +255,22 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { primeSecondLevelCacheRegions( bootMetamodel ); + // we build this before creating the runtime metamodel + // because the persisters need the SqmFunctionRegistry + // to translate SQL formulas ... but, if we fix Dialect + // as I proposed, so that it can contribute functions + // to the SqmFunctionRegistry before the QueryEngine is + // created, then we can split creation of QueryEngine + // and SqmFunctionRegistry, instantiating just the + // registry here, and doing the engine later queryEngine = QueryEngine.from( this, bootMetamodel ); - bootstrapContext.getTypeConfiguration().scope( this ); - + // this is where creation of the runtime metamodel happens final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl(); runtimeMetamodels = runtimeMetamodelsImpl; new RuntimeModelCreationContext() { final MappingMetamodelImpl mappingMetamodelImpl = - new MappingMetamodelImpl( typeConfiguration, serviceRegistry, options.getJpaCompliance() ); + new MappingMetamodelImpl( typeConfiguration, serviceRegistry ); { // need to set this before calling finishInitialization() runtimeMetamodelsImpl.setMappingMetamodel( mappingMetamodelImpl ); @@ -264,7 +278,6 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { mappingMetamodelImpl.finishInitialization( this ); // need to set this after calling finishInitialization() runtimeMetamodelsImpl.setJpaMetamodel( mappingMetamodelImpl.getJpaMetamodel() ); - } @Override @@ -334,8 +347,9 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { } }; - // this needs to happen after persisters are all ready to go... - fetchProfiles = getFetchProfiles( bootMetamodel, runtimeMetamodelsImpl ); + // this needs to happen after the mapping metamodel is + // completely built, since we need to use the persisters + fetchProfiles = getFetchProfiles( bootMetamodel, runtimeMetamodels.getMappingMetamodel() ); defaultSessionOpenOptions = createDefaultSessionOpenOptionsIfPossible(); temporarySessionOpenOptions = defaultSessionOpenOptions == null ? null : buildTemporarySessionOpenOptions(); @@ -345,6 +359,13 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { currentSessionContext = buildCurrentSessionContext(); + // re-scope the TypeConfiguration to this SessionFactory, + // now that we are (almost) fully-initialized ... note, + // we could have done this earlier, but then it's hard to + // really know or control who's calling back to us while + // we're in an incompletely-initialized state + typeConfiguration.scope( this ); + observer.sessionFactoryCreated( this ); // As last operation, delete all caches from ReflectionManager @@ -443,52 +464,6 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { } } - private static Map getFetchProfiles( - MetadataImplementor bootMetamodel, - RuntimeMetamodelsImpl runtimeMetamodels) { - final Map fetchProfiles = new HashMap<>(); - for ( org.hibernate.mapping.FetchProfile mappingProfile : bootMetamodel.getFetchProfiles() ) { - final FetchProfile fetchProfile = createFetchProfile( runtimeMetamodels, mappingProfile ); - fetchProfiles.put( fetchProfile.getName(), fetchProfile ); - } - return fetchProfiles; - } - - private static FetchProfile createFetchProfile( - RuntimeMetamodelsImpl runtimeMetamodels, - org.hibernate.mapping.FetchProfile mappingProfile) { - final FetchProfile fetchProfile = new FetchProfile( mappingProfile.getName() ); - for ( org.hibernate.mapping.FetchProfile.Fetch mappingFetch : mappingProfile.getFetches() ) { - // resolve the persister owning the fetch - final EntityPersister owner = getEntityPersister( runtimeMetamodels, fetchProfile, mappingFetch ); - - // validate the specified association fetch - final Type associationType = owner.getPropertyType( mappingFetch.getAssociation() ); - if ( associationType == null || !associationType.isAssociationType() ) { - throw new HibernateException( "Fetch profile [" + fetchProfile.getName() + "] specified an invalid association" ); - } - - // resolve the style - final Fetch.Style fetchStyle = Fetch.Style.parse( mappingFetch.getStyle() ); - - // then construct the fetch instance... - fetchProfile.addFetch( new Association( owner, mappingFetch.getAssociation() ), fetchStyle ); - ((Loadable) owner).registerAffectingFetchProfile( fetchProfile.getName() ); - } - return fetchProfile; - } - - private static EntityPersister getEntityPersister(RuntimeMetamodelsImpl runtimeMetamodels, FetchProfile fetchProfile, org.hibernate.mapping.FetchProfile.Fetch mappingFetch) { - final String entityName = runtimeMetamodels.getImportedName( mappingFetch.getEntity() ); - if ( entityName != null ) { - EntityPersister persister = runtimeMetamodels.getMappingMetamodel().getEntityDescriptor( entityName ); - if ( persister != null ) { - return persister; - } - } - throw new HibernateException( "Unable to resolve entity reference [" + mappingFetch.getEntity() - + "] in fetch profile [" + fetchProfile.getName() + "]" ); - } private static Map getSettings(SessionFactoryOptions options, SessionFactoryServiceRegistry serviceRegistry) { final Map settings = serviceRegistry.getService( ConfigurationService.class ).getSettings(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java index 219932ccab..bc866a8834 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java @@ -242,7 +242,12 @@ public class AttributeFactory { final JavaType baseJtd = context.getTypeConfiguration() .getJavaTypeRegistry() .resolveDescriptor( anyType.getReturnedClass() ); - return (DomainType) new AnyMappingDomainTypeImpl( anyType, (JavaType) baseJtd, context.getTypeConfiguration() ); + return (DomainType) new AnyMappingDomainTypeImpl( + anyType, + (JavaType) baseJtd, + context.getTypeConfiguration(), + context.getMetamodel() + ); } case EMBEDDABLE: { final Component component = (Component) typeContext.getHibernateValue(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java index 2e83a4d077..dc7747bbe7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java @@ -33,7 +33,6 @@ import org.hibernate.metamodel.model.domain.BasicDomainType; import org.hibernate.metamodel.model.domain.EmbeddableDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.IdentifiableDomainType; -import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.ManagedDomainType; import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType; import org.hibernate.metamodel.model.domain.PersistentAttribute; @@ -45,6 +44,7 @@ import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl; import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl; import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl; import org.hibernate.metamodel.model.domain.internal.PrimitiveBasicTypeImpl; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.spi.EntityJavaType; @@ -73,7 +73,7 @@ import jakarta.persistence.metamodel.Type; public class MetadataContext { private static final EntityManagerMessageLogger LOG = HEMLogging.messageLogger( MetadataContext.class ); - private final JpaMetamodel jpaMetamodel; + private final JpaMetamodelImplementor jpaMetamodel; private final RuntimeModelCreationContext runtimeModelCreationContext; private final Set knownMappedSuperclasses; @@ -103,7 +103,7 @@ public class MetadataContext { private final MappingMetamodel metamodel; public MetadataContext( - JpaMetamodel jpaMetamodel, + JpaMetamodelImplementor jpaMetamodel, MappingMetamodel mappingMetamodel, MetadataImplementor bootMetamodel, JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting, @@ -122,7 +122,7 @@ public class MetadataContext { return runtimeModelCreationContext; } - public JpaMetamodel getJpaMetamodel() { + public JpaMetamodelImplementor getJpaMetamodel() { return jpaMetamodel; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleNaturalIdMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleNaturalIdMapping.java index 148abb26ed..185f845dd5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleNaturalIdMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleNaturalIdMapping.java @@ -163,7 +163,7 @@ public class SimpleNaturalIdMapping extends AbstractNaturalIdMapping implements normalizedValue = naturalIdToLoad; } - if ( getTypeConfiguration().getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled() ) { + if ( getTypeConfiguration().getJpaCompliance().isLoadByIdComplianceEnabled() ) { return normalizedValue; } return getJavaType().coerce( normalizedValue, this ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractDomainType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractDomainType.java index 377a66dcf1..0d0768fe3d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractDomainType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractDomainType.java @@ -6,21 +6,22 @@ */ package org.hibernate.metamodel.model.domain; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.type.descriptor.java.JavaType; /** * @author Steve Ebersole */ public abstract class AbstractDomainType implements SimpleDomainType { - private final JpaMetamodel domainMetamodel; + private final JpaMetamodelImplementor domainMetamodel; private final JavaType javaType; - public AbstractDomainType(JavaType javaType, JpaMetamodel domainMetamodel) { + public AbstractDomainType(JavaType javaType, JpaMetamodelImplementor domainMetamodel) { this.javaType = javaType; this.domainMetamodel = domainMetamodel; } - protected JpaMetamodel jpaMetamodel() { + protected JpaMetamodelImplementor jpaMetamodel() { return domainMetamodel; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java index 2cf2c2d0c2..fda777cb45 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java @@ -22,6 +22,7 @@ import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource; import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource; import org.hibernate.metamodel.model.domain.internal.NonAggregatedCompositeSqmPathSource; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.spi.PrimitiveJavaType; @@ -64,7 +65,7 @@ public abstract class AbstractIdentifiableType boolean hasIdClass, boolean hasIdentifierProperty, boolean versioned, - JpaMetamodel jpaMetamodel) { + JpaMetamodelImplementor jpaMetamodel) { super( typeName, javaType, superType, jpaMetamodel ); this.hasIdClass = hasIdClass; this.hasIdentifierProperty = hasIdentifierProperty; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractManagedType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractManagedType.java index 9b427fcfc5..fd0a44d5ff 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractManagedType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractManagedType.java @@ -31,12 +31,13 @@ import jakarta.persistence.metamodel.SingularAttribute; import org.hibernate.graph.internal.SubGraphImpl; import org.hibernate.graph.spi.SubGraphImplementor; import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.RepresentationMode; -import org.hibernate.metamodel.RuntimeMetamodels; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.MappingModelHelper; import org.hibernate.metamodel.model.domain.internal.AttributeContainer; import org.hibernate.metamodel.model.domain.internal.DomainModelHelper; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.query.SemanticException; import org.hibernate.type.descriptor.java.JavaType; @@ -62,7 +63,7 @@ public abstract class AbstractManagedType String hibernateTypeName, JavaType javaType, ManagedDomainType superType, - JpaMetamodel domainMetamodel) { + JpaMetamodelImplementor domainMetamodel) { super( javaType, domainMetamodel ); this.hibernateTypeName = hibernateTypeName; this.superType = superType; @@ -197,13 +198,11 @@ public abstract class AbstractManagedType if ( attribute1 == attribute2 ) { return true; } - final RuntimeMetamodels runtimeMetamodels = jpaMetamodel().getTypeConfiguration() - .getSessionFactory() - .getRuntimeMetamodels(); - final EntityMappingType entity1 = runtimeMetamodels.getEntityMappingType( + final MappingMetamodel runtimeMetamodels = jpaMetamodel().getMappingMetamodel(); + final EntityMappingType entity1 = runtimeMetamodels.getEntityDescriptor( attribute1.getDeclaringType().getTypeName() ); - final EntityMappingType entity2 = runtimeMetamodels.getEntityMappingType( + final EntityMappingType entity2 = runtimeMetamodels.getEntityDescriptor( attribute2.getDeclaringType().getTypeName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorConverter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorConverter.java index 7708693742..692de1b4b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorConverter.java @@ -6,6 +6,7 @@ */ package org.hibernate.metamodel.model.domain.internal; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.RepresentationMode; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.persister.entity.EntityPersister; @@ -17,15 +18,19 @@ import org.hibernate.type.spi.TypeConfiguration; public class AnyDiscriminatorConverter implements BasicValueConverter { private final MetaType modelPart; - private BasicType discriminatorBasicType; - private TypeConfiguration typeConfiguration; + private final BasicType discriminatorBasicType; + private final TypeConfiguration typeConfiguration; + private final MappingMetamodel mappingMetamodel; public AnyDiscriminatorConverter( - MetaType modelPart, BasicType discriminatorBasicType, - TypeConfiguration typeConfiguration) { + MetaType modelPart, + BasicType discriminatorBasicType, + TypeConfiguration typeConfiguration, + MappingMetamodel mappingMetamodel) { this.modelPart = modelPart; this.discriminatorBasicType = discriminatorBasicType; this.typeConfiguration = typeConfiguration; + this.mappingMetamodel = mappingMetamodel; } @Override @@ -35,10 +40,7 @@ public class AnyDiscriminatorConverter implements BasicValueConverter { private final JavaType baseJtd; private final BasicType anyDiscriminatorType; - public AnyMappingDomainTypeImpl(AnyType anyType, JavaType baseJtd, TypeConfiguration typeConfiguration) { + public AnyMappingDomainTypeImpl( + AnyType anyType, + JavaType baseJtd, + TypeConfiguration typeConfiguration, + MappingMetamodel mappingMetamodel) { this.anyType = anyType; this.baseJtd = baseJtd; final MetaType discriminatorType = (MetaType) anyType.getDiscriminatorType(); @@ -33,7 +37,12 @@ public class AnyMappingDomainTypeImpl implements AnyMappingDomainType { new ConvertedBasicTypeImpl<>( null, // no name discriminatorBasicType.getJdbcType(), - new AnyDiscriminatorConverter( discriminatorType, discriminatorBasicType, typeConfiguration ) + new AnyDiscriminatorConverter( + discriminatorType, + discriminatorBasicType, + typeConfiguration, + mappingMetamodel + ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddableTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddableTypeImpl.java index 6d8b25f709..543de1b857 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddableTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddableTypeImpl.java @@ -12,7 +12,7 @@ import org.hibernate.graph.internal.SubGraphImpl; import org.hibernate.graph.spi.SubGraphImplementor; import org.hibernate.metamodel.model.domain.AbstractManagedType; import org.hibernate.metamodel.model.domain.EmbeddableDomainType; -import org.hibernate.metamodel.model.domain.JpaMetamodel; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.type.descriptor.java.JavaType; /** @@ -31,7 +31,7 @@ public class EmbeddableTypeImpl public EmbeddableTypeImpl( JavaType javaType, boolean isDynamic, - JpaMetamodel domainMetamodel) { + JpaMetamodelImplementor domainMetamodel) { super( javaType.getJavaType().getTypeName(), javaType, null, domainMetamodel ); this.isDynamic = isDynamic; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java index 9eea3516f1..31178b55d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java @@ -23,8 +23,8 @@ import org.hibernate.metamodel.model.domain.IdentifiableDomainType; import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.persister.entity.DiscriminatorMetadata; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Queryable; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.domain.SqmPath; @@ -47,7 +47,7 @@ public class EntityTypeImpl JavaType javaType, IdentifiableDomainType superType, PersistentClass persistentClass, - JpaMetamodel jpaMetamodel) { + JpaMetamodelImplementor jpaMetamodel) { super( persistentClass.getEntityName(), javaType, @@ -61,11 +61,9 @@ public class EntityTypeImpl this.jpaEntityName = persistentClass.getJpaEntityName(); - final Queryable entityDescriptor = (Queryable) jpaMetamodel.getTypeConfiguration() - .getSessionFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() - .getEntityDescriptor( getHibernateEntityName() ); + final Queryable entityDescriptor = (Queryable) + jpaMetamodel.getMappingMetamodel() + .getEntityDescriptor( getHibernateEntityName() ); final DiscriminatorMetadata discriminatorMetadata = entityDescriptor.getTypeDiscriminatorMetadata(); final DomainType discriminatorType; if ( discriminatorMetadata != null ) { @@ -83,7 +81,7 @@ public class EntityTypeImpl entityDescriptor ); } - public EntityTypeImpl(JavaType javaTypeDescriptor, JpaMetamodel jpaMetamodel) { + public EntityTypeImpl(JavaType javaTypeDescriptor, JpaMetamodelImplementor jpaMetamodel) { super( javaTypeDescriptor.getJavaTypeClass().getName(), javaTypeDescriptor, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java index b0bb703ad9..ccc3f090e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java @@ -84,7 +84,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable { } private final TypeConfiguration typeConfiguration; - private final JpaCompliance jpaCompliance; + private final MappingMetamodel mappingMetamodel; private final Map> jpaEntityTypeMap = new TreeMap<>(); // Need ordering for deterministic implementers list in SqmPolymorphicRootDescriptor private final Map, ManagedDomainType> jpaManagedTypeMap = new HashMap<>(); @@ -102,9 +102,9 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable { private final Map knownInvalidnameToImportMap = new ConcurrentHashMap<>(); - public JpaMetamodelImpl(TypeConfiguration typeConfiguration, JpaCompliance jpaCompliance) { + public JpaMetamodelImpl(TypeConfiguration typeConfiguration, MappingMetamodel mappingMetamodel) { this.typeConfiguration = typeConfiguration; - this.jpaCompliance = jpaCompliance; + this.mappingMetamodel = mappingMetamodel; } @Override @@ -114,7 +114,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable { @Override public JpaCompliance getJpaCompliance() { - return jpaCompliance; + return typeConfiguration.getJpaCompliance(); } @Override @@ -455,9 +455,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable { if ( superType != null && superType.getPersistenceType() == Type.PersistenceType.ENTITY && javaType.isAssignableFrom( superType.getJavaType() ) ) { - final EntityMappingType superMapping = typeConfiguration.getSessionFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() + final EntityMappingType superMapping = getMappingMetamodel() .getEntityDescriptor( ( (EntityDomainType) superType ).getHibernateEntityName() ); if ( !superMapping.isExplicitPolymorphism() ) { continue; @@ -465,9 +463,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable { } // it should not be added if it is mapped with explicit polymorphism itself - final EntityMappingType entityPersister = typeConfiguration.getSessionFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() + final EntityMappingType entityPersister = getMappingMetamodel() .getEntityDescriptor( entityDomainType.getHibernateEntityName() ); if ( entityPersister.isExplicitPolymorphism() ) { continue; @@ -492,6 +488,11 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable { throw new IllegalArgumentException( "Could not resolve entity reference : " + javaType.getName() ); } + @Override + public MappingMetamodel getMappingMetamodel() { + return mappingMetamodel; + } + public void processJpa( MetadataImplementor bootMetamodel, MappingMetamodel mappingMetamodel, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassTypeImpl.java index 17a2e49ac5..ebbcd7e7d9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassTypeImpl.java @@ -13,10 +13,10 @@ import org.hibernate.metamodel.UnsupportedMappingException; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.model.domain.AbstractIdentifiableType; import org.hibernate.metamodel.model.domain.IdentifiableDomainType; -import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType; import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; +import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.type.descriptor.java.JavaType; @@ -30,7 +30,7 @@ public class MappedSuperclassTypeImpl extends AbstractIdentifiableType imp JavaType javaType, MappedSuperclass mappedSuperclass, IdentifiableDomainType superType, - JpaMetamodel jpaMetamodel) { + JpaMetamodelImplementor jpaMetamodel) { super( javaType.getJavaType().getTypeName(), javaType, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java index 34c5dbad8a..a36f91d5f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java @@ -79,6 +79,7 @@ import jakarta.persistence.metamodel.EmbeddableType; import jakarta.persistence.metamodel.EntityType; import jakarta.persistence.metamodel.ManagedType; +import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY; import static org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting.determineJpaMetaModelPopulationSetting; import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting.determineJpaStaticMetaModelPopulationSetting; @@ -99,7 +100,7 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo //NOTE: we suppress deprecation warnings because at the moment we //implement a deprecated API so have to override deprecated things - private static final String[] EMPTY_IMPLEMENTORS = ArrayHelper.EMPTY_STRING_ARRAY; + private static final String[] EMPTY_IMPLEMENTORS = EMPTY_STRING_ARRAY; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // JpaMetamodel @@ -161,13 +162,10 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo private final Map implementorsCache = new ConcurrentHashMap<>(); private final Map, MappingModelExpressible> tupleTypeCache = new ConcurrentHashMap<>(); - public MappingMetamodelImpl( - TypeConfiguration typeConfiguration, - ServiceRegistry serviceRegistry, - JpaCompliance jpaCompliance) { + public MappingMetamodelImpl(TypeConfiguration typeConfiguration, ServiceRegistry serviceRegistry) { this.serviceRegistry = serviceRegistry; this.typeConfiguration = typeConfiguration; - this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, jpaCompliance ); + this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, this ); } public JpaMetamodelImplementor getJpaMetamodel() { @@ -743,7 +741,7 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo } } - return results.toArray( ArrayHelper.EMPTY_STRING_ARRAY ); + return results.toArray( EMPTY_STRING_ARRAY ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/spi/JpaMetamodelImplementor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/spi/JpaMetamodelImplementor.java index c9eb087e37..5de415562b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/spi/JpaMetamodelImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/spi/JpaMetamodelImplementor.java @@ -6,6 +6,7 @@ */ package org.hibernate.metamodel.model.domain.spi; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.model.domain.JpaMetamodel; /** @@ -14,4 +15,5 @@ import org.hibernate.metamodel.model.domain.JpaMetamodel; * @author Steve Ebersole */ public interface JpaMetamodelImplementor extends JpaMetamodel { + MappingMetamodel getMappingMetamodel(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java index 8aa53192d8..3520f431bd 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java @@ -105,7 +105,7 @@ public class QueryParameterBindingImpl implements QueryParameterBinding, J return; } - if ( ! getTypeConfiguration().getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled() ) { + if ( ! getTypeConfiguration().getJpaCompliance().isLoadByIdComplianceEnabled() ) { try { if ( bindType != null ) { value = coerce( value, bindType ); @@ -211,7 +211,7 @@ public class QueryParameterBindingImpl implements QueryParameterBinding, J bindType = queryParameter.getHibernateType(); } - if ( ! getTypeConfiguration().getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled() ) { + if ( ! getTypeConfiguration().getJpaCompliance().isLoadByIdComplianceEnabled() ) { if ( bindType != null ) { try { value = coerce( value, bindType ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java index dc39d33816..89450c0ff6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngine.java @@ -7,7 +7,6 @@ package org.hibernate.query.spi; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -28,6 +27,7 @@ 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; @@ -49,6 +49,8 @@ import org.hibernate.type.spi.TypeConfiguration; import org.jboss.logging.Logger; +import static java.util.Comparator.comparingInt; + /** * Aggregation and encapsulation of the components Hibernate uses * to execute queries (HQL, Criteria and native) @@ -56,7 +58,7 @@ import org.jboss.logging.Logger; * @author Steve Ebersole */ @Incubating -public class QueryEngine { +public class QueryEngine implements QueryParameterBindingTypeResolver { /** * The default soft reference count. @@ -67,33 +69,58 @@ public class QueryEngine { public static QueryEngine from(SessionFactoryImplementor sessionFactory, MetadataImplementor metadata) { final QueryEngineOptions queryEngineOptions = sessionFactory.getSessionFactoryOptions(); - final SqmCreationOptions sqmCreationOptions = new SqmCreationOptionsStandard( sessionFactory ); - final Dialect dialect = sessionFactory.getJdbcServices().getDialect(); - final HqlTranslator hqlTranslator = resolveHqlTranslator( - queryEngineOptions, - dialect, + return new QueryEngine( sessionFactory, - sqmCreationOptions + resolveHqlTranslator( + queryEngineOptions, + dialect, + sessionFactory, + new SqmCreationOptionsStandard( queryEngineOptions ) + ), + resolveSqmTranslatorFactory( queryEngineOptions, dialect ), + metadata, + dialect, + buildCustomFunctionRegistry( queryEngineOptions ) ); + } - final SqmTranslatorFactory sqmTranslatorFactory = resolveSqmTranslatorFactory( queryEngineOptions, dialect ); - final SqmFunctionRegistry customSqmFunctionRegistry; + private static SqmFunctionRegistry buildCustomFunctionRegistry(QueryEngineOptions queryEngineOptions) { if ( queryEngineOptions.getCustomSqmFunctionRegistry() == null ) { final Map customSqlFunctionMap = queryEngineOptions.getCustomSqlFunctionMap(); if ( customSqlFunctionMap == null || customSqlFunctionMap.isEmpty() ) { - customSqmFunctionRegistry = null; + return null; } else { - customSqmFunctionRegistry = new SqmFunctionRegistry(); + SqmFunctionRegistry customSqmFunctionRegistry = new SqmFunctionRegistry(); customSqlFunctionMap.forEach( customSqmFunctionRegistry::register ); + return customSqmFunctionRegistry; } } else { - customSqmFunctionRegistry = queryEngineOptions.getCustomSqmFunctionRegistry(); + return queryEngineOptions.getCustomSqmFunctionRegistry(); } + } - return new QueryEngine( + 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(), @@ -107,22 +134,13 @@ public class QueryEngine { buildInterpretationCache( sessionFactory::getStatistics, sessionFactory.getProperties() ), metadata.getTypeConfiguration(), dialect, - customSqmFunctionRegistry, - sessionFactory.getServiceRegistry() + customFunctionRegistry, + sessionFactory.getServiceRegistry(), + sessionFactory ); } - 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; - - public QueryEngine( + private QueryEngine( String uuid, String name, JpaCompliance jpaCompliance, @@ -137,7 +155,9 @@ public class QueryEngine { TypeConfiguration typeConfiguration, Dialect dialect, SqmFunctionRegistry userDefinedRegistry, - ServiceRegistry serviceRegistry) { + ServiceRegistry serviceRegistry, + SessionFactoryImplementor sessionFactory) { + this.queryParameterBindingTypeResolver = sessionFactory; this.namedObjectRepository = Objects.requireNonNull( namedObjectRepository ); this.sqmTranslatorFactory = sqmTranslatorFactory; this.nativeQueryInterpreter = Objects.requireNonNull( nativeQueryInterpreter ); @@ -151,7 +171,8 @@ public class QueryEngine { this, jpaMetamodelAccess, serviceRegistry, - criteriaValueHandlingMode + criteriaValueHandlingMode, + sessionFactory ); this.sqmFunctionRegistry = new SqmFunctionRegistry(); @@ -212,6 +233,8 @@ public class QueryEngine { this.preferredSqlTypeCodeForBoolean = preferredSqlTypeCodeForBoolean; dialect.initializeFunctionRegistry( this ); + SessionFactoryImplementor sessionFactory = jpaMetamodel.getTypeConfiguration().getSessionFactory(); + this.queryParameterBindingTypeResolver = sessionFactory; this.criteriaBuilder = new SqmCriteriaNodeBuilder( uuid, name, @@ -219,7 +242,8 @@ public class QueryEngine { this, () -> jpaMetamodel, serviceRegistry, - criteriaValueHandlingMode + criteriaValueHandlingMode, + sessionFactory ); final SqmCreationContext sqmCreationContext = new SqmCreationContext() { @@ -261,51 +285,6 @@ public class QueryEngine { ); } -// public QueryEngine( -// JpaMetamodel domainModel, -// ServiceRegistry serviceRegistry, -// SessionFactoryOptions runtimeOptions, -// SqmCreationContext sqmCreationContext, -// SqmCreationOptions sqmCreationOptions, -// Map properties, -// NamedQueryRepository namedQueryRepository) { -// final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); -// final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); -// final Dialect dialect = jdbcEnvironment.getDialect(); -// -// this.namedQueryRepository = namedQueryRepository; -// -// this.hqlTranslator = resolveHqlTranslator( -// runtimeOptions, -// dialect, -// sqmCreationContext, -// sqmCreationOptions -// ); -// -// this.sqmTranslatorFactory = resolveSqmTranslatorFactory( -// runtimeOptions, -// dialect, -// sqmCreationContext, -// sqmCreationOptions -// ); -// -// this.criteriaBuilder = new SqmCriteriaNodeBuilder( -// this, -// domainModel, -// serviceRegistry -// ); -// -// this.nativeQueryInterpreter = serviceRegistry.getService( NativeQueryInterpreter.class ); -// -// this.interpretationCache = buildInterpretationCache( properties ); -// -// this.sqmFunctionRegistry = new SqmFunctionRegistry(); -// dialect.initializeFunctionRegistry( this ); -// if ( runtimeOptions.getSqmFunctionRegistry() != null ) { -// runtimeOptions.getSqmFunctionRegistry().overlay( sqmFunctionRegistry ); -// } -// } - private static HqlTranslator resolveHqlTranslator( QueryEngineOptions runtimeOptions, Dialect dialect, @@ -314,12 +293,12 @@ public class QueryEngine { if ( runtimeOptions.getCustomHqlTranslator() != null ) { return runtimeOptions.getCustomHqlTranslator(); } - - if ( dialect.getHqlTranslator() != null ) { + else if ( dialect.getHqlTranslator() != null ) { return dialect.getHqlTranslator(); } - - return new StandardHqlTranslator( sqmCreationContext, sqmCreationOptions ); + else { + return new StandardHqlTranslator( sqmCreationContext, sqmCreationOptions ); + } } private static SqmTranslatorFactory resolveSqmTranslatorFactory( @@ -328,26 +307,26 @@ public class QueryEngine { if ( runtimeOptions.getCustomSqmTranslatorFactory() != null ) { return runtimeOptions.getCustomSqmTranslatorFactory(); } - - if ( dialect.getSqmTranslatorFactory() != null ) { + else if ( dialect.getSqmTranslatorFactory() != null ) { return dialect.getSqmTranslatorFactory(); } - - return new StandardSqmTranslatorFactory(); + else { + return new StandardSqmTranslatorFactory(); + } } private static List sortedFunctionContributors(ServiceRegistry serviceRegistry) { List contributors = new ArrayList<>( serviceRegistry.getService( ClassLoaderService.class ) .loadJavaServices( FunctionContributor.class ) ); - contributors.sort( Comparator.comparingInt( FunctionContributor::ordinal ) - .thenComparing( a -> a.getClass().getCanonicalName() ) ); + contributors.sort( comparingInt( FunctionContributor::ordinal ) + .thenComparing( a -> a.getClass().getCanonicalName() ) ); return contributors; } private static QueryInterpretationCache buildInterpretationCache( Supplier statisticsSupplier, - Map properties) { + Map properties) { final boolean explicitUseCache = ConfigurationHelper.getBoolean( AvailableSettings.QUERY_PLAN_CACHE_ENABLED, properties, @@ -437,4 +416,14 @@ public class QueryEngine { public int getPreferredSqlTypeCodeForBoolean() { return preferredSqlTypeCodeForBoolean; } + + @Override + public BindableType resolveParameterBindType(T bindValue) { + return queryParameterBindingTypeResolver.resolveParameterBindType( bindValue ); + } + + @Override + public BindableType resolveParameterBindType(Class clazz) { + return queryParameterBindingTypeResolver.resolveParameterBindType( clazz ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngineOptions.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngineOptions.java index 108354d837..5df5238497 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngineOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryEngineOptions.java @@ -8,6 +8,7 @@ package org.hibernate.query.spi; import java.util.Map; +import org.hibernate.jpa.spi.JpaCompliance; import org.hibernate.query.hql.HqlTranslator; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.function.SqmFunctionRegistry; @@ -66,4 +67,6 @@ public interface QueryEngineOptions { * target of the mutation is a multi-table entity. */ SqmMultiTableInsertStrategy getCustomSqmMultiTableInsertStrategy(); + + JpaCompliance getJpaCompliance(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java index 14ccb42a7e..54b88aa79a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.query.criteria.HibernateCriteriaBuilder; import org.hibernate.query.criteria.JpaCoalesce; @@ -646,4 +647,6 @@ public interface NodeBuilder extends HibernateCriteriaBuilder { BasicType getIntegerType(); BasicType getCharacterType(); + + SessionFactoryImplementor getSessionFactory(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCreationOptionsStandard.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCreationOptionsStandard.java index 9d1c89d984..e854b22129 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCreationOptionsStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCreationOptionsStandard.java @@ -6,21 +6,21 @@ */ package org.hibernate.query.sqm.internal; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.hql.spi.SqmCreationOptions; +import org.hibernate.query.spi.QueryEngineOptions; /** * @author Steve Ebersole */ public class SqmCreationOptionsStandard implements SqmCreationOptions { - private final SessionFactoryImplementor sessionFactory; + private final QueryEngineOptions queryEngineOptions; - public SqmCreationOptionsStandard(SessionFactoryImplementor sessionFactory) { - this.sessionFactory = sessionFactory; + public SqmCreationOptionsStandard(QueryEngineOptions queryEngineOptions) { + this.queryEngineOptions = queryEngineOptions; } @Override public boolean useStrictJpaCompliance() { - return sessionFactory.getSessionFactoryOptions().getJpaCompliance().isJpaQueryComplianceEnabled(); + return queryEngineOptions.getJpaCompliance().isJpaQueryComplianceEnabled(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java index f0da0aee93..c34f0eb7a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java @@ -176,21 +176,6 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SqmCriteriaNodeBuilder.class ); - /** - * Simplified creation from a SessionFactory - */ - public static SqmCriteriaNodeBuilder create(SessionFactoryImplementor sf) { - return new SqmCriteriaNodeBuilder( - sf.getUuid(), - sf.getName(), - sf.getSessionFactoryOptions().getJpaCompliance().isJpaQueryComplianceEnabled(), - sf.getQueryEngine(), - () -> sf.getRuntimeMetamodels().getJpaMetamodel(), - sf.getServiceRegistry(), - sf.getSessionFactoryOptions().getCriteriaValueHandlingMode() - ); - } - private final String uuid; private final String name; private final transient boolean jpaComplianceEnabled; @@ -198,6 +183,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, private final transient Supplier domainModelAccess; private final transient ServiceRegistry serviceRegistry; private final transient ValueHandlingMode criteriaValueHandlingMode; + private final transient SessionFactoryImplementor sessionFactory; private transient BasicType booleanType; private transient BasicType integerType; private transient BasicType characterType; @@ -210,7 +196,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, QueryEngine queryEngine, Supplier domainModelAccess, ServiceRegistry serviceRegistry, - ValueHandlingMode criteriaValueHandlingMode) { + ValueHandlingMode criteriaValueHandlingMode, + SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; this.uuid = uuid; this.name = name; this.jpaComplianceEnabled = jpaComplianceEnabled; @@ -222,7 +210,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, this.extensions = new HashMap<>(); for (CriteriaBuilderExtension extension : ServiceLoader.load( CriteriaBuilderExtension.class ) ) { HibernateCriteriaBuilder builder = extension.extend( this ); - extensions.put(extension.getRegistrationKey(), builder); + extensions.put( extension.getRegistrationKey(), builder ); } } @@ -236,6 +224,11 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, return jpaComplianceEnabled; } + @Override + public SessionFactoryImplementor getSessionFactory() { + return sessionFactory; + } + @Override public BasicType getBooleanType() { final BasicType booleanType = this.booleanType; @@ -466,7 +459,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, throw new SemanticException( "Path should refer to a to-one attribute : " + path ); } - return new SqmFkExpression<>( (SqmEntityValuedSimplePath) path, this ); + return new SqmFkExpression<>( (SqmEntityValuedSimplePath) path, this ); } @Override @@ -623,7 +616,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, expressibleType = (DomainType) typeConfiguration.resolveTupleType( sqmExpressions ); } else { - expressibleType = typeConfiguration.getSessionFactory().getJpaMetamodel().embeddable( tupleType ); + expressibleType = domainModelAccess.get().embeddable( tupleType ); } return tuple( expressibleType, sqmExpressions ); } @@ -1194,12 +1187,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, return new SqmLiteralNull<>( this ); } - final BindableType valueParamType = queryEngine.getTypeConfiguration() - .getSessionFactory() - .resolveParameterBindType( value ); + final BindableType valueParamType = queryEngine.resolveParameterBindType( value ); final SqmExpressible sqmExpressible = valueParamType == null ? null - : valueParamType.resolveExpressible( getTypeConfiguration().getSessionFactory() ); + : valueParamType.resolveExpressible( sessionFactory ); return new SqmLiteral<>( value, sqmExpressible, this ); } @@ -1235,7 +1226,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, final TypeConfiguration typeConfiguration = getTypeConfiguration(); final BasicType basicTypeForJavaType = typeConfiguration.getBasicTypeForJavaType( resultClass ); final SqmExpressible sqmExpressible = basicTypeForJavaType == null - ? typeConfiguration.getSessionFactory().getJpaMetamodel().managedType( resultClass ) + ? domainModelAccess.get().managedType( resultClass ) : basicTypeForJavaType; return new SqmLiteralNull<>(sqmExpressible, this ); } @@ -1263,7 +1254,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, @Override public JpaCriteriaParameter parameter(Class paramClass) { - return parameter( paramClass, (String) null ); + return parameter( paramClass, null ); } @Override @@ -1727,7 +1718,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, this ); } - final SqmExpressible expressible = bindableType.resolveExpressible( getTypeConfiguration().getSessionFactory() ); + final SqmExpressible expressible = bindableType.resolveExpressible( sessionFactory ); T coercedValue = expressible.getExpressibleJavaType().coerce( value, this::getTypeConfiguration ); if ( isInstance( bindableType, coercedValue ) ) { return new ValueBindJpaCriteriaParameter<>( @@ -1739,7 +1730,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, else { // ignore typeInferenceSource and fallback the value type return new ValueBindJpaCriteriaParameter<>( - queryEngine.getTypeConfiguration().getSessionFactory().resolveParameterBindType( value ), + queryEngine.resolveParameterBindType( value ), value, this ); @@ -1753,7 +1744,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, if ( bindableType.getBindableJavaType().isInstance( value ) ) { return true; } - return bindableType.resolveExpressible( getTypeConfiguration().getSessionFactory() ) + return bindableType.resolveExpressible( sessionFactory ) .getExpressibleJavaType() .isInstance( value ); } @@ -1792,7 +1783,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, } else { return new ValueBindJpaCriteriaParameter<>( - queryEngine.getTypeConfiguration().getSessionFactory().resolveParameterBindType( value ), + queryEngine.resolveParameterBindType( value ), value, this ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentTypesValidator.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentTypesValidator.java index f70ede64f4..f02541f7b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentTypesValidator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentTypesValidator.java @@ -7,12 +7,12 @@ package org.hibernate.query.sqm.produce.function; import org.hibernate.QueryException; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPartContainer; import org.hibernate.metamodel.model.domain.EntityDomainType; -import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.domain.SqmPath; @@ -75,18 +75,21 @@ public class ArgumentTypesValidator implements ArgumentsValidator { * that is run at startup for named queries, and can be done in an IDE. */ @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) { - delegate.validate(arguments, functionName, queryEngine); + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + delegate.validate( arguments, functionName, metamodel ); int count = 0; for (SqmTypedNode argument : arguments) { - JdbcTypeIndicators indicators = queryEngine.getTypeConfiguration().getCurrentBaseSqlTypeIndicators(); + JdbcTypeIndicators indicators = metamodel.getTypeConfiguration().getCurrentBaseSqlTypeIndicators(); SqmExpressible nodeType = argument.getNodeType(); FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1]; if ( nodeType!=null ) { JavaType javaType = nodeType.getExpressibleJavaType(); if (javaType != null) { try { - final JdbcType jdbcType = getJdbcType( queryEngine, argument, indicators, javaType ); + final JdbcType jdbcType = getJdbcType( metamodel, argument, indicators, javaType ); checkType( count, functionName, type, jdbcType.getDefaultSqlTypeCode(), @@ -126,14 +129,14 @@ public class ArgumentTypesValidator implements ArgumentsValidator { } private JdbcType getJdbcType( - QueryEngine queryEngine, + MappingMetamodel metamodel, SqmTypedNode argument, JdbcTypeIndicators indicators, JavaType javaType) { // For enum types, we must try to resolve the JdbcMapping of a possible path // to be sure we use the correct JdbcType for the validation final JdbcMapping mapping = javaType.getJavaTypeClass().isEnum() - ? getJdbcMapping( argument, queryEngine ) + ? getJdbcMapping( argument, metamodel ) : null; if ( mapping == null ) { return javaType.getRecommendedJdbcType( indicators ); @@ -143,25 +146,25 @@ public class ArgumentTypesValidator implements ArgumentsValidator { } } - private JdbcMapping getJdbcMapping(SqmTypedNode argument, QueryEngine queryEngine) { + private JdbcMapping getJdbcMapping(SqmTypedNode argument, MappingMetamodel metamodel) { if ( argument instanceof SqmPath ) { final SqmPath path = (SqmPath) argument; - final ModelPartContainer modelPartContainer = getModelPartContainer( path.getLhs(), queryEngine ); + final ModelPartContainer modelPartContainer = getModelPartContainer( path.getLhs(), metamodel ); final ModelPart part = modelPartContainer.findSubPart( path.getReferencedPathSource().getPathName(), null ); return part.getJdbcMappings().get( 0 ); } return null; } - private ModelPartContainer getModelPartContainer(SqmPath path, QueryEngine queryEngine) { + private ModelPartContainer getModelPartContainer(SqmPath path, MappingMetamodel metamodel) { final SqmPath lhs = path.getLhs(); if ( lhs == null ) { assert path instanceof SqmFrom; final EntityDomainType entityDomainType = (EntityDomainType) path.getNodeType().getSqmPathType(); - return queryEngine.getTypeConfiguration().getSessionFactory().getRuntimeMetamodels().getEntityMappingType( entityDomainType.getHibernateEntityName() ); + return metamodel.getEntityDescriptor( entityDomainType.getHibernateEntityName() ); } else { - final ModelPartContainer modelPartContainer = getModelPartContainer( lhs, queryEngine ); + final ModelPartContainer modelPartContainer = getModelPartContainer( lhs, metamodel ); return (ModelPartContainer) modelPartContainer.findSubPart( path.getReferencedPathSource().getPathName(), null ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentsValidator.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentsValidator.java index 67a9fb8a6c..9d858f8a24 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentsValidator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentsValidator.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.sqm.produce.function; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -22,10 +23,19 @@ import java.util.List; */ public interface ArgumentsValidator { /** - * Perform validation that may be done using the {@link SqmTypedNode} - * tree and assigned Java types. + * Perform validation that may be done using the {@link SqmTypedNode} tree and assigned Java types. + * + * @deprecated Use {@link #validate(List, String, MappingMetamodel)} */ - void validate(List> arguments, String functionName, QueryEngine queryEngine); + @Deprecated(since = "6.2") + default void validate(List> arguments, String functionName, QueryEngine queryEngine) { + validate( arguments, functionName, queryEngine.getTypeConfiguration().getSessionFactory().getMappingMetamodel() ); + } + + /** + * Perform validation that may be done using the {@link SqmTypedNode} tree and assigned Java types. + */ + default void validate(List> arguments, String functionName, MappingMetamodel metamodel) {} /** * Pretty-print the signature of the argument list. @@ -35,8 +45,7 @@ public interface ArgumentsValidator { } /** - * Perform validation that requires the {@link SqlAstNode} tree and - * assigned JDBC types. + * Perform validation that requires the {@link SqlAstNode} tree and assigned JDBC types. */ default void validateSqlTypes(List arguments, String functionName) {} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardArgumentsValidators.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardArgumentsValidators.java index 9c1b21b6d6..3d8dd34bdc 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardArgumentsValidators.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardArgumentsValidators.java @@ -7,13 +7,14 @@ package org.hibernate.query.sqm.produce.function; import org.hibernate.QueryException; -import org.hibernate.query.spi.QueryEngine; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.query.sqm.tree.SqmTypedNode; -import java.util.Arrays; import java.util.List; import java.util.Locale; +import static java.util.Arrays.asList; + /** * @author Steve Ebersole */ @@ -28,9 +29,6 @@ public final class StandardArgumentsValidators { * Static validator for performing no validation */ public static final ArgumentsValidator NONE = new ArgumentsValidator() { - @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) {} - @Override public String getSignature() { return "([arg0[, ...]])"; @@ -42,8 +40,11 @@ public final class StandardArgumentsValidators { */ public static final ArgumentsValidator NO_ARGS = new ArgumentsValidator() { @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) { - if (!arguments.isEmpty()) { + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + if ( !arguments.isEmpty() ) { throw new QueryException( String.format( Locale.ROOT, @@ -67,8 +68,11 @@ public final class StandardArgumentsValidators { } return new ArgumentsValidator() { @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) { - if (arguments.size() < minNumOfArgs) { + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + if ( arguments.size() < minNumOfArgs ) { throw new QueryException( String.format( Locale.ROOT, @@ -101,8 +105,11 @@ public final class StandardArgumentsValidators { public static ArgumentsValidator exactly(int number) { return new ArgumentsValidator() { @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) { - if (arguments.size() != number) { + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + if ( arguments.size() != number ) { throw new QueryException( String.format( Locale.ROOT, @@ -137,8 +144,11 @@ public final class StandardArgumentsValidators { public static ArgumentsValidator max(int maxNumOfArgs) { return new ArgumentsValidator() { @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) { - if (arguments.size() > maxNumOfArgs) { + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + if ( arguments.size() > maxNumOfArgs ) { throw new QueryException( String.format( Locale.ROOT, @@ -169,7 +179,10 @@ public final class StandardArgumentsValidators { public static ArgumentsValidator between(int minNumOfArgs, int maxNumOfArgs) { return new ArgumentsValidator() { @Override - public void validate(List> arguments, String functionName, QueryEngine queryEngine) { + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { if (arguments.size() < minNumOfArgs || arguments.size() > maxNumOfArgs) { throw new QueryException( String.format( @@ -203,9 +216,14 @@ public final class StandardArgumentsValidators { } public static ArgumentsValidator of(Class javaType) { - return (arguments, functionName, queryEngine) -> arguments.forEach( - arg -> { - Class argType = arg.getNodeJavaType().getJavaTypeClass(); + return new ArgumentsValidator() { + @Override + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + for ( SqmTypedNode argument : arguments ) { + Class argType = argument.getNodeJavaType().getJavaTypeClass(); if ( !javaType.isAssignableFrom( argType ) ) { throw new QueryException( String.format( @@ -218,16 +236,27 @@ public final class StandardArgumentsValidators { ); } } - ); + } + }; } public static ArgumentsValidator composite(ArgumentsValidator... validators) { - return composite( Arrays.asList( validators ) ); + return composite( asList( validators ) ); } public static ArgumentsValidator composite(List validators) { - return (arguments, functionName, queryEngine) -> validators.forEach( - individualValidator -> individualValidator.validate( arguments, functionName, queryEngine) - ); + return new ArgumentsValidator() { + @Override + public void validate( + List> arguments, + String functionName, + MappingMetamodel metamodel) { + validators.forEach( individualValidator -> individualValidator.validate( + arguments, + functionName, + metamodel + ) ); + } + }; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java index c2d0def927..495fd2b776 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java @@ -205,10 +205,8 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements final SqmAttributeJoin lhsAttributeJoin = (SqmAttributeJoin) lhs; if ( lhsAttributeJoin.getReferencedPathSource() instanceof EntityDomainType ) { final String entityName = ( (EntityDomainType) lhsAttributeJoin.getReferencedPathSource() ).getHibernateEntityName(); - return (ModelPartContainer) creationState.getCreationContext().getQueryEngine() - .getTypeConfiguration() - .getSessionFactory() - .getRuntimeMetamodels() + return (ModelPartContainer) creationState.getCreationContext() + .getJpaMetamodel() .getMappingMetamodel() .getEntityDescriptor( entityName ) .findSubPart( attributeJoin.getAttribute().getName(), null ); @@ -230,10 +228,8 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements assert lhs instanceof SqmCrossJoin; entityName = ( (SqmCrossJoin) lhs ).getEntityName(); } - return (ModelPartContainer) creationState.getCreationContext().getQueryEngine() - .getTypeConfiguration() - .getSessionFactory() - .getRuntimeMetamodels() + return (ModelPartContainer) creationState.getCreationContext() + .getJpaMetamodel() .getMappingMetamodel() .getEntityDescriptor( entityName ) .findSubPart( attributeJoin.getAttribute().getName(), null ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java index d71cc0cd50..f7a0ef5e47 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java @@ -20,8 +20,8 @@ import org.hibernate.query.sqm.tree.SqmCopyContext; /** * {@link JpaParameterExpression} created via JPA {@link jakarta.persistence.criteria.CriteriaBuilder}. - * - * Each occurrence of a JpaParameterExpression results in a unique SqmParameter + *

+ * Each occurrence of a {@code JpaParameterExpression} results in a unique {@link SqmParameter}. * * @see ParameterMetadata * @see NodeBuilder#parameter @@ -54,9 +54,7 @@ public class JpaCriteriaParameter if ( type == null ) { return null; } - return type.resolveExpressible( - nodeBuilder.getQueryEngine().getTypeConfiguration().getSessionFactory() - ); + return type.resolveExpressible( nodeBuilder.getSessionFactory() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExpressionHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExpressionHelper.java index 5b76d8b860..2dded63a9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExpressionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExpressionHelper.java @@ -36,16 +36,16 @@ import org.hibernate.usertype.internal.AbstractTimeZoneStorageCompositeUserType; */ public class SqmExpressionHelper { public static SqmExpressible toSqmType(BindableType parameterType, SqmCreationState creationState) { - return toSqmType( parameterType, creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration() ); + return toSqmType( parameterType, creationState.getCreationContext().getNodeBuilder().getSessionFactory() ); } public static SqmExpressible toSqmType(BindableType anticipatedType, NodeBuilder nodeBuilder) { - return toSqmType( anticipatedType, nodeBuilder.getTypeConfiguration() ); + return toSqmType( anticipatedType, nodeBuilder.getSessionFactory() ); } - public static SqmExpressible toSqmType(BindableType anticipatedType, TypeConfiguration typeConfiguration) { - return toSqmType( anticipatedType, typeConfiguration.getSessionFactory() ); - } +// public static SqmExpressible toSqmType(BindableType anticipatedType, TypeConfiguration typeConfiguration) { +// return toSqmType( anticipatedType, typeConfiguration.getSessionFactory() ); +// } public static SqmExpressible toSqmType(BindableType anticipatedType, SessionFactoryImplementor sessionFactory) { if ( anticipatedType == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/AnyType.java b/hibernate-core/src/main/java/org/hibernate/type/AnyType.java index 627baf3144..fcfdc01847 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AnyType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AnyType.java @@ -32,11 +32,12 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; -import org.hibernate.pretty.MessageHelper; -import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; import org.hibernate.type.spi.TypeConfiguration; +import static org.hibernate.pretty.MessageHelper.infoString; +import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer; + /** * Handles "any" mappings * @@ -121,32 +122,37 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT @Override public int compare(Object x, Object y) { + throw new UnsupportedOperationException( "compare() not implemented for AnyType" ); + } + + @Override + public int compare(Object x, Object y, SessionFactoryImplementor factory) { if ( x == null ) { // if y is also null, return that they are the same (no option for "UNKNOWN") - // if y is not null, return that y is "greater" (-1 because the result is from the perspective of - // the first arg: x) + // if y is not null, return that y is "greater" + // (-1 because the result is from the perspective of the first arg: x) return y == null ? 0 : -1; } else if ( y == null ) { - // x is not null, but y is. return that x is "greater" + // x is not null, but y is, return that x is "greater" return 1; } // At this point we know both are non-null. - final Object xId = extractIdentifier( x ); - final Object yId = extractIdentifier( y ); + final Object xId = extractIdentifier( x, factory ); + final Object yId = extractIdentifier( y, factory ); return getIdentifierType().compare( xId, yId ); } - private Object extractIdentifier(Object entity) { - final EntityPersister concretePersister = guessEntityPersister( entity ); + private Object extractIdentifier(Object entity, SessionFactoryImplementor factory) { + final EntityPersister concretePersister = guessEntityPersister( entity, factory ); return concretePersister == null ? null : concretePersister.getIdentifier( entity, null ); } - private EntityPersister guessEntityPersister(Object object) { + private EntityPersister guessEntityPersister(Object object, SessionFactoryImplementor factory) { if ( typeConfiguration == null ) { return null; } @@ -155,7 +161,7 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT // this code is largely copied from Session's bestGuessEntityName Object entity = object; - final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity ); + final LazyInitializer lazyInitializer = extractLazyInitializer( entity ); if ( lazyInitializer != null ) { if ( lazyInitializer.isUninitialized() ) { entityName = lazyInitializer.getEntityName(); @@ -164,9 +170,7 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT } if ( entityName == null ) { - final MappingMetamodelImplementor mappingMetamodel = typeConfiguration.getSessionFactory() - .getRuntimeMetamodels() - .getMappingMetamodel(); + final MappingMetamodelImplementor mappingMetamodel = factory.getRuntimeMetamodels().getMappingMetamodel(); for ( EntityNameResolver resolver : mappingMetamodel.getEntityNameResolvers() ) { entityName = resolver.resolveEntityName( entity ); if ( entityName != null ) { @@ -180,7 +184,7 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT entityName = object.getClass().getName(); } - return typeConfiguration.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor( entityName ); + return factory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor( entityName ); } @Override @@ -201,7 +205,7 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT final ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) old; final boolean[] idCheckable = new boolean[checkable.length-1]; System.arraycopy( checkable, 1, idCheckable, 0, idCheckable.length ); - return ( checkable[0] && !holder.entityName.equals( session.bestGuessEntityName( current ) ) ) + return checkable[0] && !holder.entityName.equals( session.bestGuessEntityName( current ) ) || identifierType.isModified( holder.id, getIdentifier( current, session ), idCheckable, session ); } @@ -270,11 +274,11 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT return ""; } - String entityName = factory.bestGuessEntityName(value); + final String entityName = factory.bestGuessEntityName(value); final EntityPersister descriptor = entityName == null ? null : factory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor( entityName ); - return MessageHelper.infoString( descriptor, value, factory ); + return infoString( descriptor, value, factory ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java index d30d08e31a..4714af64f3 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java @@ -153,8 +153,8 @@ public class BasicTypeRegistry implements Serializable { } /** - * Find an existing BasicType registration for the given JavaType descriptor and - * JdbcType descriptor combo or create (and register) one. + * Find an existing {@link BasicType} registration for the given {@link JavaType} + * descriptor and {@link JdbcType} descriptor combo or create (and register) one. */ public BasicType resolve(JavaType jtdToUse, JdbcType stdToUse) { return resolve( @@ -163,10 +163,11 @@ public class BasicTypeRegistry implements Serializable { () -> { final BasicTypeImpl basicType = new BasicTypeImpl<>( jtdToUse, stdToUse ); - // if we are still building mappings, register this ad-hoc type via a - // unique code. this is to support envers + // if we are still building mappings, register this ad-hoc type + // via a unique code. this is to support envers try { - typeConfiguration.getMetadataBuildingContext().getBootstrapContext().registerAdHocBasicType( basicType ); + typeConfiguration.getMetadataBuildingContext().getBootstrapContext() + .registerAdHocBasicType( basicType ); } catch (Exception ignore) { } diff --git a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java index ee55a1f6d9..4b14d823fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java @@ -216,12 +216,8 @@ public abstract class EntityType extends AbstractType implements AssociationType try { return ReflectHelper.classForName( entityName ); } - catch (ClassNotFoundException cnfe) { - return typeConfiguration.getSessionFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() - .getEntityDescriptor( entityName ) - .getMappedClass(); + catch ( ClassNotFoundException cnfe ) { + return typeConfiguration.entityClassForEntityName( entityName ); } } @@ -256,7 +252,35 @@ public abstract class EntityType extends AbstractType implements AssociationType @Override public int compare(Object x, Object y) { - return 0; //TODO: entities CAN be compared, by PK, fix this! -> only if/when we can extract the id values.... + throw new UnsupportedOperationException( "compare() not implemented for EntityType" ); + } + + @Override + public int compare(Object x, Object y, SessionFactoryImplementor factory) { + if ( x == null ) { + // if y is also null, return that they are the same (no option for "UNKNOWN") + // if y is not null, return that y is "greater" + // (-1 because the result is from the perspective of the first arg: x) + return y == null ? 0 : -1; + } + else if ( y == null ) { + // x is not null, but y is, return that x is "greater" + return 1; + } + + // At this point we know both are non-null. + final Object xId = extractIdentifier( x, factory ); + final Object yId = extractIdentifier( y, factory ); + + return getIdentifierType( factory ).compare( xId, yId ); + } + + private Object extractIdentifier(Object entity, SessionFactoryImplementor factory) { + final EntityPersister concretePersister = + factory.getMappingMetamodel().getEntityDescriptor( associatedEntityName ); + return concretePersister == null + ? null + : concretePersister.getIdentifier( entity, null ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java index 9346acbf01..ebb7a4419b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java @@ -30,7 +30,6 @@ import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.EnumValueConverter; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; -import org.hibernate.type.descriptor.java.BasicJavaType; import org.hibernate.type.descriptor.java.EnumJavaType; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; diff --git a/hibernate-core/src/main/java/org/hibernate/type/Type.java b/hibernate-core/src/main/java/org/hibernate/type/Type.java index 57c7239348..1d70b6bc82 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/Type.java +++ b/hibernate-core/src/main/java/org/hibernate/type/Type.java @@ -218,6 +218,9 @@ public interface Type extends Serializable { */ int compare(Object x, Object y); + default int compare(Object x, Object y, SessionFactoryImplementor sessionFactory) { + return compare( x, y ); + } /** * Should the parent be considered dirty, given both the old and current value? * @@ -480,5 +483,4 @@ public interface Type extends Serializable { * @return array indicating column nullness for a value instance */ boolean[] toColumnNullness(Object value, Mapping mapping); - } diff --git a/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java b/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java index 4347a1fde8..2aa0f8130a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java +++ b/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java @@ -32,6 +32,7 @@ import java.util.function.Function; import org.hibernate.HibernateException; import org.hibernate.Incubating; +import org.hibernate.Internal; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; import org.hibernate.TimeZoneStorageStrategy; @@ -44,6 +45,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.id.uuid.LocalObjectUuidHelper; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.SessionFactoryRegistry; +import org.hibernate.jpa.spi.JpaCompliance; import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMappingContainer; @@ -147,7 +149,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { } public JdbcTypeIndicators getCurrentBaseSqlTypeIndicators() { - return scope.getCurrentBaseSqlTypeIndicators(); + return scope; } public Map> getJdbcToHibernateTypeContributionMap() { @@ -165,7 +167,10 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { * stages a {@code TypeConfiguration} passes through. * * @return The {@link MetadataBuildingContext} + * + * @deprecated This operation is not very typesafe, and we're migrating away from its use */ + @Deprecated(since = "6.2") public MetadataBuildingContext getMetadataBuildingContext() { return scope.getMetadataBuildingContext(); } @@ -211,7 +216,10 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { * * @throws HibernateException if the {@code TypeConfiguration} is not currently scoped * to a {@link SessionFactory} (in a "runtime stage"). + * + * @deprecated This operation is not very typesafe, and we're migrating away from its use */ + @Deprecated(since = "6.2") public SessionFactoryImplementor getSessionFactory() { return scope.getSessionFactory(); } @@ -228,6 +236,21 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { return scope.getServiceRegistry(); } + /** + * Obtain the {@link JpaCompliance} setting. + */ + public JpaCompliance getJpaCompliance() { + return scope.getJpaCompliance(); + } + + /** + * Workaround for an issue faced in {@link org.hibernate.type.EntityType#getReturnedClass()}. + */ + @Internal + public Class entityClassForEntityName(String entityName) { + return scope.entityClassForEntityName(entityName); + } + @Override public void sessionFactoryCreated(SessionFactory factory) { // Instead of allowing scope#setSessionFactory to influence this, we use the SessionFactoryObserver callback @@ -365,7 +388,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { *

* Each stage or phase is considered a scope for the {@link TypeConfiguration}. */ - private static class Scope implements Serializable { + private static class Scope implements JdbcTypeIndicators, Serializable { private final TypeConfiguration typeConfiguration; private transient MetadataBuildingContext metadataBuildingContext; @@ -374,71 +397,65 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { private String sessionFactoryName; private String sessionFactoryUuid; - private final transient JdbcTypeIndicators currentSqlTypeIndicators = new JdbcTypeIndicators() { - @Override - public TypeConfiguration getTypeConfiguration() { - return typeConfiguration; - } + @Override + public TypeConfiguration getTypeConfiguration() { + return typeConfiguration; + } - @Override - public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() { - return sessionFactory == null - ? getMetadataBuildingContext().getBuildingOptions().getDefaultTimeZoneStorage() - : getTypeConfiguration().getSessionFactory().getSessionFactoryOptions().getDefaultTimeZoneStorageStrategy(); - } + @Override + public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() { + return sessionFactory == null + ? metadataBuildingContext.getBuildingOptions().getDefaultTimeZoneStorage() + : sessionFactory.getSessionFactoryOptions().getDefaultTimeZoneStorageStrategy(); + } - @Override - public int getPreferredSqlTypeCodeForBoolean() { - return sessionFactory == null - ? getMetadataBuildingContext().getPreferredSqlTypeCodeForBoolean() - : getTypeConfiguration().getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean(); - } + @Override + public int getPreferredSqlTypeCodeForBoolean() { + return sessionFactory == null + ? metadataBuildingContext.getPreferredSqlTypeCodeForBoolean() + : sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean(); + } - @Override - public int getPreferredSqlTypeCodeForDuration() { - return sessionFactory == null - ? getMetadataBuildingContext().getPreferredSqlTypeCodeForDuration() - : getTypeConfiguration().getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForDuration(); - } + @Override + public int getPreferredSqlTypeCodeForDuration() { + return sessionFactory == null + ? metadataBuildingContext.getPreferredSqlTypeCodeForDuration() + : sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForDuration(); + } - @Override - public int getPreferredSqlTypeCodeForUuid() { - return sessionFactory == null - ? getMetadataBuildingContext().getPreferredSqlTypeCodeForUuid() - : getTypeConfiguration().getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForUuid(); - } + @Override + public int getPreferredSqlTypeCodeForUuid() { + return sessionFactory == null + ? metadataBuildingContext.getPreferredSqlTypeCodeForUuid() + : sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForUuid(); + } - @Override - public int getPreferredSqlTypeCodeForInstant() { - return sessionFactory == null - ? getMetadataBuildingContext().getPreferredSqlTypeCodeForInstant() - : getTypeConfiguration().getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForInstant(); - } + @Override + public int getPreferredSqlTypeCodeForInstant() { + return sessionFactory == null + ? metadataBuildingContext.getPreferredSqlTypeCodeForInstant() + : sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForInstant(); + } - @Override - public int getPreferredSqlTypeCodeForArray() { - return sessionFactory == null - ? getMetadataBuildingContext().getPreferredSqlTypeCodeForArray() - : getTypeConfiguration().getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForArray(); - } - }; + @Override + public int getPreferredSqlTypeCodeForArray() { + return sessionFactory == null + ? metadataBuildingContext.getPreferredSqlTypeCodeForArray() + : sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForArray(); + } - public Scope(TypeConfiguration typeConfiguration) { + private Scope(TypeConfiguration typeConfiguration) { this.typeConfiguration = typeConfiguration; } - public JdbcTypeIndicators getCurrentBaseSqlTypeIndicators() { - return currentSqlTypeIndicators; - } - - public MetadataBuildingContext getMetadataBuildingContext() { + private MetadataBuildingContext getMetadataBuildingContext() { if ( metadataBuildingContext == null ) { throw new HibernateException( "TypeConfiguration is not currently scoped to MetadataBuildingContext" ); } return metadataBuildingContext; } - public ServiceRegistry getServiceRegistry() { + private ServiceRegistry getServiceRegistry() { if ( metadataBuildingContext != null ) { return metadataBuildingContext.getBootstrapContext().getServiceRegistry(); } @@ -448,11 +465,21 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { return null; } - public void setMetadataBuildingContext(MetadataBuildingContext metadataBuildingContext) { + private JpaCompliance getJpaCompliance() { + if ( metadataBuildingContext != null ) { + return metadataBuildingContext.getBootstrapContext().getJpaCompliance(); + } + else if ( sessionFactory != null ) { + return sessionFactory.getSessionFactoryOptions().getJpaCompliance(); + } + return null; + } + + private void setMetadataBuildingContext(MetadataBuildingContext metadataBuildingContext) { this.metadataBuildingContext = metadataBuildingContext; } - public SessionFactoryImplementor getSessionFactory() { + private SessionFactoryImplementor getSessionFactory() { if ( sessionFactory == null ) { if ( sessionFactoryName == null && sessionFactoryUuid == null ) { throw new HibernateException( "TypeConfiguration was not yet scoped to SessionFactory" ); @@ -477,26 +504,30 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { * * @param factory The {@link SessionFactory} to which the {@link TypeConfiguration} is being bound */ - void setSessionFactory(SessionFactoryImplementor factory) { + private void setSessionFactory(SessionFactoryImplementor factory) { if ( this.sessionFactory != null ) { log.scopingTypesToSessionFactoryAfterAlreadyScoped( this.sessionFactory, factory ); } else { this.sessionFactoryUuid = factory.getUuid(); - String factoryName = factory.getSessionFactoryOptions().getSessionFactoryName(); - if ( factoryName == null ) { - final CfgXmlAccessService cfgXmlAccessService = factory.getServiceRegistry() - .getService( CfgXmlAccessService.class ); - if ( cfgXmlAccessService.getAggregatedConfig() != null ) { - factoryName = cfgXmlAccessService.getAggregatedConfig().getSessionFactoryName(); - } - } - this.sessionFactoryName = factoryName; + this.sessionFactoryName = getFactoryName( factory ); } this.sessionFactory = factory; } - public void unsetSessionFactory(SessionFactory factory) { + private static String getFactoryName(SessionFactoryImplementor factory) { + final String factoryName = factory.getSessionFactoryOptions().getSessionFactoryName(); + if ( factoryName == null ) { + final CfgXmlAccessService cfgXmlAccessService = factory.getServiceRegistry() + .getService( CfgXmlAccessService.class ); + if ( cfgXmlAccessService.getAggregatedConfig() != null ) { + return cfgXmlAccessService.getAggregatedConfig().getSessionFactoryName(); + } + } + return factoryName; + } + + private void unsetSessionFactory(SessionFactory factory) { log.debugf( "Un-scoping TypeConfiguration [%s] from SessionFactory [%s]", this, factory ); this.sessionFactory = null; } @@ -522,6 +553,12 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { return this; } + + private Class entityClassForEntityName(String entityName) { + return sessionFactory == null + ? metadataBuildingContext.getMetadataCollector().getEntityBinding( entityName ).getMappedClass() + : sessionFactory.getMappingMetamodel().findEntityDescriptor( entityName ).getMappedClass(); + } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java index 86f771fe1a..e3eb7a7b06 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java @@ -31,6 +31,7 @@ import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Environment; @@ -223,8 +224,12 @@ public class DefaultCatalogAndSchemaTest { break; case SESSION_FACTORY_SERVICE_REGISTRY: serviceRegistry = createStandardServiceRegistry( configuredDefaultCatalog, configuredDefaultSchema ); - sfb = new SessionFactoryBuilderImpl( metadata, new SessionFactoryOptionsBuilder( serviceRegistry, - ((MetadataImpl) metadata).getBootstrapContext() ) ); + BootstrapContext bootstrapContext = ((MetadataImpl) metadata).getBootstrapContext(); + sfb = new SessionFactoryBuilderImpl( + metadata, + new SessionFactoryOptionsBuilder( serviceRegistry, bootstrapContext), + bootstrapContext + ); break; default: throw new IllegalStateException( "Unknown settings mode: " + settingsMode ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeDeleteCollectionWithCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeDeleteCollectionWithCollectionInDefaultFetchGroupFalseTest.java index 1079845798..019d6a9efb 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeDeleteCollectionWithCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeDeleteCollectionWithCollectionInDefaultFetchGroupFalseTest.java @@ -72,7 +72,7 @@ public class CascadeDeleteCollectionWithCollectionInDefaultFetchGroupFalseTest e // We want to test with this setting set to false explicitly, // because another test already takes care of the default. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeOnUninitializedWithCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeOnUninitializedWithCollectionInDefaultFetchGroupFalseTest.java index 44427188cc..7de4299175 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeOnUninitializedWithCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/cascade/CascadeOnUninitializedWithCollectionInDefaultFetchGroupFalseTest.java @@ -80,7 +80,7 @@ public class CascadeOnUninitializedWithCollectionInDefaultFetchGroupFalseTest ex // We want to test with this setting set to false explicitly, // because another test already takes care of the default. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingCollectionInDefaultFetchGroupFalseTest.java index ab2cbd6c05..e9559a096b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dirty/DirtyTrackingCollectionInDefaultFetchGroupFalseTest.java @@ -67,7 +67,7 @@ public class DirtyTrackingCollectionInDefaultFetchGroupFalseTest extends BaseCor // We want to test with this setting set to false explicitly, // because another test already takes care of the default. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/LazyCollectionDetachWithCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/LazyCollectionDetachWithCollectionInDefaultFetchGroupFalseTest.java index fb4043de7d..fc7ae7a71c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/LazyCollectionDetachWithCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/LazyCollectionDetachWithCollectionInDefaultFetchGroupFalseTest.java @@ -22,7 +22,6 @@ import org.hibernate.boot.internal.SessionFactoryBuilderImpl; import org.hibernate.boot.internal.SessionFactoryOptionsBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.spi.SessionFactoryBuilderService; -import org.hibernate.orm.test.bytecode.enhancement.dirty.DirtyTrackingCollectionInDefaultFetchGroupTest; import org.hibernate.proxy.HibernateProxy; import org.hibernate.testing.TestForIssue; @@ -72,7 +71,7 @@ public class LazyCollectionDetachWithCollectionInDefaultFetchGroupFalseTest exte // We want to test with this setting set to false explicitly, // because another test already takes care of the default. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/cache/UninitializedAssociationsInCacheTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/cache/UninitializedAssociationsInCacheTest.java index ae3b566dac..5c7b7f158e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/cache/UninitializedAssociationsInCacheTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/cache/UninitializedAssociationsInCacheTest.java @@ -65,7 +65,7 @@ public class UninitializedAssociationsInCacheTest extends BaseCoreFunctionalTest ); // This test only makes sense if association properties *can* be uninitialized. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/BytecodeEnhancedLazyLoadingOnDeletedEntityTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/BytecodeEnhancedLazyLoadingOnDeletedEntityTest.java index 4cf43634dc..d8036cc377 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/BytecodeEnhancedLazyLoadingOnDeletedEntityTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/BytecodeEnhancedLazyLoadingOnDeletedEntityTest.java @@ -63,7 +63,7 @@ public class BytecodeEnhancedLazyLoadingOnDeletedEntityTest ); // This test only makes sense if association properties *can* be uninitialized. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java index 14287147df..8de68fd7b2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java @@ -80,7 +80,7 @@ public class SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTe // We want to test with this setting set to false explicitly, // because another test already takes care of the default. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/ondemandload/OnDemandLoadWithCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/ondemandload/OnDemandLoadWithCollectionInDefaultFetchGroupFalseTest.java index 87b9d49d32..0e55fb4540 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/ondemandload/OnDemandLoadWithCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/ondemandload/OnDemandLoadWithCollectionInDefaultFetchGroupFalseTest.java @@ -26,7 +26,6 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.spi.SessionFactoryBuilderService; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; -import org.hibernate.orm.test.bytecode.enhancement.lazy.proxy.SimpleUpdateTestWithLazyLoading; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; @@ -83,7 +82,7 @@ public class OnDemandLoadWithCollectionInDefaultFetchGroupFalseTest extends Base // We want to test with this setting set to false explicitly, // because another test already takes care of the default. optionsBuilder.enableCollectionInDefaultFetchGroup( false ); - return new SessionFactoryBuilderImpl( metadata, optionsBuilder ); + return new SessionFactoryBuilderImpl( metadata, optionsBuilder, bootstrapContext ); } ); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java index 1be617ad5a..9b9dbe86c0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java @@ -12,7 +12,6 @@ import java.util.Properties; import java.util.concurrent.Callable; import org.hibernate.annotations.common.reflection.ReflectionManager; -import org.hibernate.boot.internal.MetadataImpl; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.boot.spi.MetadataImplementor; @@ -186,7 +185,10 @@ public class Configuration { // todo: there are places that need bits built from the revinfo entity configuration // this exists here as a way to pass it down in an immutable way to any consumer of this class - final ReflectionManager reflectionManager = metadata.getMetadataBuildingOptions().getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext().getReflectionManager(); + final ReflectionManager reflectionManager = + metadata.getMetadataBuildingOptions().getTypeConfiguration() + .getMetadataBuildingContext().getBootstrapContext() + .getReflectionManager(); this.revisionInfo = new RevisionInfoConfiguration( this, metadata, reflectionManager ); }