From ec5bbe4546be3f8f5279166ada03b37ebf374b6a Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 22 Nov 2024 13:26:49 -0600 Subject: [PATCH] HHH-18534 - Remove the org.hibernate.boot.models.categorize package --- .../InFlightMetadataCollectorImpl.java | 2 +- .../process/spi/MetadataBuildingProcess.java | 3 +- .../boot/models/AttributeNature.java | 21 + .../org/hibernate/boot/models/Copied.java | 21 - .../spi => }/JpaEventListenerStyle.java | 2 +- .../MultipleAttributeNaturesException.java | 15 +- .../ModelCategorizationLogging.java | 21 - .../AbstractIdentifiableTypeMetadata.java | 244 ------------ .../internal/AbstractManagedTypeMetadata.java | 176 --------- ...ractPersistentAttributeMemberResolver.java | 99 ----- .../internal/AggregatedKeyMappingImpl.java | 26 -- .../internal/AttributeMetadataImpl.java | 43 -- .../internal/BasicKeyMappingImpl.java | 24 -- .../internal/CategorizationHelper.java | 234 ----------- .../internal/CategorizedDomainModelImpl.java | 81 ---- .../internal/EntityHierarchyBuilder.java | 238 ----------- .../internal/EntityHierarchyImpl.java | 318 --------------- .../internal/EntityTypeMetadataImpl.java | 369 ------------------ .../internal/HierarchyMetadataCollector.java | 310 --------------- .../internal/HierarchyTypeConsumer.java | 17 - .../internal/LifecycleCallbackCollector.java | 129 ------ .../MappedSuperclassTypeMetadataImpl.java | 88 ----- .../ModelCategorizationContextImpl.java | 67 ---- .../internal/NonAggregatedKeyMappingImpl.java | 57 --- ...dardPersistentAttributeMemberResolver.java | 315 --------------- .../boot/models/categorize/package-info.java | 26 -- .../categorize/spi/AggregatedKeyMapping.java | 15 - .../categorize/spi/AllMemberConsumer.java | 15 - .../categorize/spi/AttributeConsumer.java | 15 - .../categorize/spi/AttributeMetadata.java | 46 --- .../categorize/spi/BasicKeyMapping.java | 11 - .../models/categorize/spi/CacheRegion.java | 130 ------ .../spi/CategorizedDomainModel.java | 101 ----- .../spi/ClassAttributeAccessType.java | 56 --- .../categorize/spi/CompositeKeyMapping.java | 14 - .../categorize/spi/EntityHierarchy.java | 82 ---- .../categorize/spi/EntityTypeMetadata.java | 87 ----- .../spi/IdentifiableTypeMetadata.java | 71 ---- .../models/categorize/spi/KeyMapping.java | 18 - .../spi/ManagedResourcesProcessor.java | 230 ----------- .../categorize/spi/ManagedTypeMetadata.java | 50 --- .../spi/MappedSuperclassTypeMetadata.java | 17 - .../spi/ModelCategorizationContext.java | 33 -- .../categorize/spi/NaturalIdCacheRegion.java | 39 -- .../spi/NonAggregatedKeyMapping.java | 34 -- .../PersistentAttributeMemberResolver.java | 41 -- .../spi/SingleAttributeKeyMapping.java | 32 -- .../models/categorize/spi/TableOwner.java | 13 - .../internal/ClassLoaderServiceLoading.java | 2 +- .../DomainModelCategorizationCollector.java | 50 +-- .../internal/GlobalRegistrationsImpl.java | 2 +- .../models/spi/ConversionRegistration.java | 21 +- .../boot/models/spi/JpaEventListener.java | 2 +- .../xml/internal/XmlAnnotationHelper.java | 2 +- .../boot/models/SourceModelTestHelper.java | 2 +- .../xml/globals/JpaEventListenerTests.java | 76 +++- 56 files changed, 118 insertions(+), 4135 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/AttributeNature.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/Copied.java rename hibernate-core/src/main/java/org/hibernate/boot/models/{categorize/spi => }/JpaEventListenerStyle.java (92%) delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/ModelCategorizationLogging.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractIdentifiableTypeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractManagedTypeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractPersistentAttributeMemberResolver.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AggregatedKeyMappingImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AttributeMetadataImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/BasicKeyMappingImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizationHelper.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizedDomainModelImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyBuilder.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityTypeMetadataImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyMetadataCollector.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyTypeConsumer.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/LifecycleCallbackCollector.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/MappedSuperclassTypeMetadataImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ModelCategorizationContextImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/NonAggregatedKeyMappingImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/StandardPersistentAttributeMemberResolver.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/package-info.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AggregatedKeyMapping.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AllMemberConsumer.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeConsumer.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/BasicKeyMapping.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CacheRegion.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CategorizedDomainModel.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ClassAttributeAccessType.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CompositeKeyMapping.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityHierarchy.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityTypeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/IdentifiableTypeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/KeyMapping.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedResourcesProcessor.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedTypeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/MappedSuperclassTypeMetadata.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ModelCategorizationContext.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NaturalIdCacheRegion.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NonAggregatedKeyMapping.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/PersistentAttributeMemberResolver.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/SingleAttributeKeyMapping.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/TableOwner.java rename hibernate-core/src/main/java/org/hibernate/boot/models/{categorize => }/internal/ClassLoaderServiceLoading.java (96%) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index f39b55bf76..0d61ce73ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -59,7 +59,7 @@ import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass; import org.hibernate.boot.model.source.spi.LocalMetadataBuildingContext; -import org.hibernate.boot.models.categorize.internal.ClassLoaderServiceLoading; +import org.hibernate.boot.models.internal.ClassLoaderServiceLoading; import org.hibernate.boot.models.internal.GlobalRegistrationsImpl; import org.hibernate.boot.models.internal.ModelsHelper; import org.hibernate.boot.models.spi.GlobalRegistrations; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/process/spi/MetadataBuildingProcess.java b/hibernate-core/src/main/java/org/hibernate/boot/model/process/spi/MetadataBuildingProcess.java index e69c8fddfb..2ed3821bb1 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/process/spi/MetadataBuildingProcess.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/process/spi/MetadataBuildingProcess.java @@ -230,7 +230,8 @@ public class MetadataBuildingProcess { return metadataCollector.buildMetadataInstance( rootMetadataBuildingContext ); } - private static void coordinateProcessors( + @Internal + public static void coordinateProcessors( ManagedResources managedResources, MetadataBuildingOptions options, MetadataBuildingContextRootImpl rootMetadataBuildingContext, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/AttributeNature.java b/hibernate-core/src/main/java/org/hibernate/boot/models/AttributeNature.java new file mode 100644 index 0000000000..b4502957ac --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/AttributeNature.java @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.boot.models; + +/** + * An enum defining the nature (categorization) of a persistent attribute. + * + * @see jakarta.persistence.metamodel.Attribute.PersistentAttributeType + */ +public enum AttributeNature { + BASIC, + EMBEDDED, + ANY, + TO_ONE, + ELEMENT_COLLECTION, + MANY_TO_ANY, + MANY_TO_MANY, + ONE_TO_MANY +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/Copied.java b/hibernate-core/src/main/java/org/hibernate/boot/models/Copied.java deleted file mode 100644 index bcc2cfc805..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/Copied.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Indicates that the class is copied from hibernate-core and should ultimately use that one - * - * @author Steve Ebersole - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Copied { - Class value() default void.class; -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/JpaEventListenerStyle.java b/hibernate-core/src/main/java/org/hibernate/boot/models/JpaEventListenerStyle.java similarity index 92% rename from hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/JpaEventListenerStyle.java rename to hibernate-core/src/main/java/org/hibernate/boot/models/JpaEventListenerStyle.java index a3ff3aab3f..32ec2d0bfd 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/JpaEventListenerStyle.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/JpaEventListenerStyle.java @@ -2,7 +2,7 @@ * SPDX-License-Identifier: LGPL-2.1-or-later * Copyright Red Hat Inc. and Hibernate Authors */ -package org.hibernate.boot.models.categorize.spi; +package org.hibernate.boot.models; /** * JPA defines 2 ways events callbacks can happen... diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/MultipleAttributeNaturesException.java b/hibernate-core/src/main/java/org/hibernate/boot/models/MultipleAttributeNaturesException.java index 321039ac19..5a6ce0b629 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/MultipleAttributeNaturesException.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/MultipleAttributeNaturesException.java @@ -6,20 +6,21 @@ package org.hibernate.boot.models; import java.util.EnumSet; -import org.hibernate.MappingException; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; +import org.hibernate.AnnotationException; +import org.hibernate.Incubating; /** - * Condition where an attribute indicates multiple {@linkplain AttributeMetadata.AttributeNature natures} + * Condition where an attribute indicates multiple {@linkplain AttributeNature natures} * * @author Steve Ebersole */ -public class MultipleAttributeNaturesException extends MappingException { +@Incubating +public class MultipleAttributeNaturesException extends AnnotationException { private final String attributeName; public MultipleAttributeNaturesException( String attributeName, - EnumSet natures) { + EnumSet natures) { super( craftMessage( attributeName, natures ) ); this.attributeName = attributeName; } @@ -28,12 +29,12 @@ public class MultipleAttributeNaturesException extends MappingException { return attributeName; } - private static String craftMessage(String attributeName, EnumSet natures) { + private static String craftMessage(String attributeName, EnumSet natures) { final StringBuilder buffer = new StringBuilder( "Attribute `" ) .append( attributeName ) .append( "` expressed multiple natures [" ); String separator = ""; - for ( AttributeMetadata.AttributeNature nature : natures ) { + for ( AttributeNature nature : natures ) { buffer.append( separator ); buffer.append( nature.name() ); separator = ","; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/ModelCategorizationLogging.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/ModelCategorizationLogging.java deleted file mode 100644 index 5c00e56da2..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/ModelCategorizationLogging.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize; - -import org.hibernate.Internal; - -import org.jboss.logging.Logger; - -/** - * todo : find the proper min/max id range - * - * @author Steve Ebersole - */ -@Internal -public interface ModelCategorizationLogging { - String NAME = "org.hibernate.models.orm"; - - Logger MODEL_CATEGORIZATION_LOGGER = Logger.getLogger( NAME ); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractIdentifiableTypeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractIdentifiableTypeMetadata.java deleted file mode 100644 index 8628772a52..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractIdentifiableTypeMetadata.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; - -import org.hibernate.boot.models.categorize.spi.ClassAttributeAccessType; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.categorize.spi.IdentifiableTypeMetadata; -import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle; -import org.hibernate.boot.models.categorize.spi.MappedSuperclassTypeMetadata; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.internal.util.collections.ArrayHelper; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; - -import jakarta.persistence.AccessType; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.ExcludeDefaultListeners; -import jakarta.persistence.ExcludeSuperclassListeners; - - -/** - * @author Steve Ebersole - */ -public abstract class AbstractIdentifiableTypeMetadata - extends AbstractManagedTypeMetadata - implements IdentifiableTypeMetadata { - private final EntityHierarchy hierarchy; - private final IdentifiableTypeMetadata superType; - private final Set subTypes = new HashSet<>(); - private final ClassAttributeAccessType classLevelAccessType; - - /** - * Used when creating the hierarchy root-root - * - * @param implicitAccessType This is the hierarchy default - */ - public AbstractIdentifiableTypeMetadata( - ClassDetails classDetails, - EntityHierarchy hierarchy, - MappedSuperclassTypeMetadata superTypeMetadata, - AccessType implicitAccessType, - ModelCategorizationContext processingContext) { - super( classDetails, processingContext ); - - this.hierarchy = hierarchy; - this.superType = superTypeMetadata; - - this.classLevelAccessType = CategorizationHelper.determineAccessType( classDetails, implicitAccessType ); - } - - - public AbstractIdentifiableTypeMetadata( - ClassDetails classDetails, - EntityHierarchy hierarchy, - IdentifiableTypeMetadata superType, - ModelCategorizationContext processingContext) { - super( classDetails, processingContext ); - - assert superType != null; - - this.hierarchy = hierarchy; - this.superType = superType; - - // this is arguably more logical, but the specification is very clear that this should come - // from the hierarchy default not the super in section _2.3.2 Explicit Access Type_ - //this.accessType = CategorizationHelper.determineAccessType( classDetails, superType.getAccessType() ); - this.classLevelAccessType = CategorizationHelper.determineAccessType( classDetails, hierarchy.getDefaultAccessType() ); - } - - protected void postInstantiate(boolean rootEntityOrSubclass, HierarchyTypeConsumer typeConsumer) { - typeConsumer.acceptType( this ); - - // now we can effectively walk subs, although we skip that for the mapped-superclasses - // "above" the root entity - if ( rootEntityOrSubclass ) { - walkSubclasses( typeConsumer ); - } - - // the idea here is to collect up class-level annotations and to apply - // the maps from supers - collectConversionInfo(); - collectAttributeOverrides(); - collectAssociationOverrides(); - } - - private void walkSubclasses(HierarchyTypeConsumer typeConsumer) { - walkSubclasses( getClassDetails(), typeConsumer ); - } - - private void walkSubclasses(ClassDetails base, HierarchyTypeConsumer typeConsumer) { - final ClassDetailsRegistry classDetailsRegistry = getModelContext().getClassDetailsRegistry(); - classDetailsRegistry.forEachDirectSubType( base.getName(), (subClassDetails) -> { - final AbstractIdentifiableTypeMetadata subTypeMetadata; - if ( CategorizationHelper.isEntity( subClassDetails ) ) { - subTypeMetadata = new EntityTypeMetadataImpl( - subClassDetails, - getHierarchy(), - this, - typeConsumer, - getModelContext() - ); - addSubclass( subTypeMetadata ); - } - else if ( CategorizationHelper.isMappedSuperclass( subClassDetails ) ) { - subTypeMetadata = new MappedSuperclassTypeMetadataImpl( - subClassDetails, - getHierarchy(), - this, - typeConsumer, - getModelContext() - ); - addSubclass( subTypeMetadata ); - } - else { - // skip over "intermediate" sub-types - walkSubclasses( subClassDetails, typeConsumer ); - } - } ); - - } - - protected void addSubclass(IdentifiableTypeMetadata subclass) { - subTypes.add( subclass ); - } - - @Override - public EntityHierarchy getHierarchy() { - return hierarchy; - } - - @Override - public IdentifiableTypeMetadata getSuperType() { - return superType; - } - - @Override - public boolean isAbstract() { - return getClassDetails().isAbstract(); - } - - @Override - public boolean hasSubTypes() { - // assume this is called only after its constructor is complete - return !subTypes.isEmpty(); - } - - @Override - public int getNumberOfSubTypes() { - return subTypes.size(); - } - - @Override - public void forEachSubType(Consumer consumer) { - // assume this is called only after its constructor is complete - subTypes.forEach( consumer ); - } - - @Override - public Iterable getSubTypes() { - // assume this is called only after its constructor is complete - return subTypes; - } - - @Override - public ClassAttributeAccessType getClassLevelAccessType() { - return classLevelAccessType; - } - - protected void collectConversionInfo() { - // we only need to do this on root - } - - protected void collectAttributeOverrides() { - // we only need to do this on root - } - - protected void collectAssociationOverrides() { - // we only need to do this on root - } - - protected List collectHierarchyEventListeners(JpaEventListener localCallback) { - final ClassDetails classDetails = getClassDetails(); - - final List combined = new ArrayList<>(); - - if ( !classDetails.hasDirectAnnotationUsage( ExcludeSuperclassListeners.class ) ) { - final IdentifiableTypeMetadata superType = getSuperType(); - if ( superType != null ) { - combined.addAll( superType.getHierarchyJpaEventListeners() ); - } - } - - applyLocalEventListeners( combined::add ); - - if ( localCallback != null ) { - combined.add( localCallback ); - } - - return combined; - } - - private void applyLocalEventListeners(Consumer consumer) { - final ClassDetails classDetails = getClassDetails(); - - final EntityListeners entityListenersAnnotation = classDetails.getDirectAnnotationUsage( EntityListeners.class ); - if ( entityListenersAnnotation == null ) { - return; - } - - final Class[] entityListenerClasses = entityListenersAnnotation.value(); - if ( CollectionHelper.isEmpty( entityListenerClasses ) ) { - return; - } - - ArrayHelper.forEach( entityListenerClasses, (listenerClass) -> { - consumer.accept( JpaEventListener.from( - JpaEventListenerStyle.LISTENER, - getModelContext().getClassDetailsRegistry().findClassDetails( listenerClass.getName() ) - ) ); - } ); - } - - protected List collectCompleteEventListeners(ModelCategorizationContext modelContext) { - final ClassDetails classDetails = getClassDetails(); - if ( classDetails.hasDirectAnnotationUsage( ExcludeDefaultListeners.class ) ) { - return getHierarchyJpaEventListeners(); - } - - final List combined = new ArrayList<>(); - combined.addAll( modelContext.getDefaultEventListeners() ); - combined.addAll( getHierarchyJpaEventListeners() ); - return combined; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractManagedTypeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractManagedTypeMetadata.java deleted file mode 100644 index dcd62f6364..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractManagedTypeMetadata.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.hibernate.boot.model.source.spi.AttributePath; -import org.hibernate.boot.model.source.spi.AttributeRole; -import org.hibernate.boot.model.source.spi.NaturalIdMutability; -import org.hibernate.boot.models.categorize.spi.AllMemberConsumer; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.ManagedTypeMetadata; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.internal.util.IndexedConsumer; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.MemberDetails; - -import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; - -/** - * Models metadata about a JPA {@linkplain jakarta.persistence.metamodel.ManagedType managed-type}. - * - * @author Hardy Ferentschik - * @author Steve Ebersole - * @author Brett Meyer - */ -public abstract class AbstractManagedTypeMetadata implements ManagedTypeMetadata { - private final ClassDetails classDetails; - private final ModelCategorizationContext modelContext; - - private final AttributePath attributePathBase; - private final AttributeRole attributeRoleBase; - - /** - * This form is intended for construction of the root of an entity hierarchy - * and its mapped-superclasses - */ - public AbstractManagedTypeMetadata(ClassDetails classDetails, ModelCategorizationContext modelContext) { - this.classDetails = classDetails; - this.modelContext = modelContext; - this.attributeRoleBase = new AttributeRole( classDetails.getName() ); - this.attributePathBase = new AttributePath(); - } - - /** - * This form is used to create Embedded references - * - * @param classDetails The Embeddable descriptor - * @param attributeRoleBase The base for the roles of attributes created *from* here - * @param attributePathBase The base for the paths of attributes created *from* here - */ - public AbstractManagedTypeMetadata( - ClassDetails classDetails, - AttributeRole attributeRoleBase, - AttributePath attributePathBase, - ModelCategorizationContext modelContext) { - this.classDetails = classDetails; - this.modelContext = modelContext; - this.attributeRoleBase = attributeRoleBase; - this.attributePathBase = attributePathBase; - } - - public ClassDetails getClassDetails() { - return classDetails; - } - - public ModelCategorizationContext getModelContext() { - return modelContext; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - AbstractManagedTypeMetadata that = (AbstractManagedTypeMetadata) o; - return Objects.equals( classDetails.getName(), that.classDetails.getName() ); - } - - @Override - public int hashCode() { - return Objects.hash( classDetails ); - } - - @Override - public String toString() { - return "ManagedTypeMetadata(" + classDetails.getName() + ")"; - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // attribute handling - - protected abstract List attributeList(); - - @Override - public int getNumberOfAttributes() { - return attributeList().size(); - } - - @Override - public Collection getAttributes() { - return attributeList(); - } - - @Override - public AttributeMetadata findAttribute(String name) { - final List attributeList = attributeList(); - for ( int i = 0; i < attributeList.size(); i++ ) { - final AttributeMetadata attribute = attributeList.get( i ); - if ( attribute.getName().equals( name ) ) { - return attribute; - } - } - return null; - } - - @Override - public void forEachAttribute(IndexedConsumer consumer) { - for ( int i = 0; i < attributeList().size(); i++ ) { - consumer.accept( i, attributeList().get( i ) ); - } - } - - protected List resolveAttributes(AllMemberConsumer memberConsumer) { - final List backingMembers = getModelContext() - .getPersistentAttributeMemberResolver() - .resolveAttributesMembers( classDetails, getClassLevelAccessType(), memberConsumer ); - - final List attributeList = arrayList( backingMembers.size() ); - - for ( MemberDetails backingMember : backingMembers ) { - final AttributeMetadata attribute = new AttributeMetadataImpl( - backingMember.resolveAttributeName(), - CategorizationHelper.determineAttributeNature( classDetails, backingMember ), - backingMember - ); - attributeList.add( attribute ); - } - - return attributeList; - } - - // @Override -// public List> findAnnotations(AnnotationDescriptor type) { -// return classDetails.getAnnotations( type ); -// } -// -// @Override -// public void forEachAnnotation(AnnotationDescriptor type, Consumer> consumer) { -// classDetails.forEachAnnotation( type, consumer ); -// } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Stuff affecting attributes built from this managed type. - - public boolean canAttributesBeInsertable() { - return true; - } - - public boolean canAttributesBeUpdatable() { - return true; - } - - public NaturalIdMutability getContainerNaturalIdMutability() { - return NaturalIdMutability.NOT_NATURAL_ID; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractPersistentAttributeMemberResolver.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractPersistentAttributeMemberResolver.java deleted file mode 100644 index 05b24c1790..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AbstractPersistentAttributeMemberResolver.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Function; - -import org.hibernate.boot.models.categorize.spi.AllMemberConsumer; -import org.hibernate.boot.models.categorize.spi.ClassAttributeAccessType; -import org.hibernate.boot.models.categorize.spi.PersistentAttributeMemberResolver; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.FieldDetails; -import org.hibernate.models.spi.MemberDetails; -import org.hibernate.models.spi.MethodDetails; - -import jakarta.persistence.Transient; - -/** - * "Template" support for writing PersistentAttributeMemberResolver - * implementations. - * - * @author Steve Ebersole - */ -public abstract class AbstractPersistentAttributeMemberResolver implements PersistentAttributeMemberResolver { - - /** - * This is the call that represents the bulk of the work needed to resolve - * the persistent attribute members. It is the strategy specific portion - * for sure. - *

- * The expectation is to - * Here is the call that most likely changes per strategy. This occurs - * immediately after we have determined all the fields and methods marked as - * transient. The expectation is to - * - * @param transientFieldChecker Check whether a field is annotated as @Transient - * @param transientMethodChecker Check whether a method is annotated as @Transient - * @param classDetails The Jandex ClassInfo describing the type for which to resolve members - * @param classLevelAccessType The AccessType determined for the class default - */ - protected abstract List resolveAttributesMembers( - Function transientFieldChecker, - Function transientMethodChecker, - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType); - - @Override - public List resolveAttributesMembers( - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType, - AllMemberConsumer memberConsumer) { - - final Set transientFields = new HashSet<>(); - final Set transientMethods = new HashSet<>(); - collectMembersMarkedTransient( - transientFields::add, - transientMethods::add, - classDetails, - memberConsumer - ); - - return resolveAttributesMembers( - transientFields::contains, - transientMethods::contains, - classDetails, - classLevelAccessType - ); - } - - protected void collectMembersMarkedTransient( - final Consumer transientFieldConsumer, - final Consumer transientMethodConsumer, - ClassDetails classDetails, - AllMemberConsumer memberConsumer) { - final List fields = classDetails.getFields(); - for ( int i = 0; i < fields.size(); i++ ) { - final FieldDetails fieldDetails = fields.get( i ); - memberConsumer.acceptMember( fieldDetails ); - if ( fieldDetails.hasDirectAnnotationUsage( Transient.class ) ) { - transientFieldConsumer.accept( fieldDetails ); - } - } - - final List methods = classDetails.getMethods(); - for ( int i = 0; i < methods.size(); i++ ) { - final MethodDetails methodDetails = methods.get( i ); - memberConsumer.acceptMember( methodDetails ); - if ( methodDetails.hasDirectAnnotationUsage( Transient.class ) ) { - transientMethodConsumer.accept( methodDetails ); - } - } - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AggregatedKeyMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AggregatedKeyMappingImpl.java deleted file mode 100644 index 1e4d8799a7..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AggregatedKeyMappingImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import org.hibernate.boot.models.categorize.spi.AggregatedKeyMapping; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; - -/** - * @author Steve Ebersole - */ -public class AggregatedKeyMappingImpl implements AggregatedKeyMapping { - private final AttributeMetadata attribute; - - public AggregatedKeyMappingImpl(AttributeMetadata attribute) { - this.attribute = attribute; - } - - @Override - public AttributeMetadata getAttribute() { - return attribute; - } - - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AttributeMetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AttributeMetadataImpl.java deleted file mode 100644 index 216b80d7ae..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/AttributeMetadataImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.models.spi.MemberDetails; - -/** - * @author Steve Ebersole - */ -public class AttributeMetadataImpl implements AttributeMetadata { - private final String name; - private final AttributeNature nature; - private final MemberDetails member; - - public AttributeMetadataImpl(String name, AttributeNature nature, MemberDetails member) { - this.name = name; - this.nature = nature; - this.member = member; - } - - @Override - public String getName() { - return name; - } - - @Override - public AttributeNature getNature() { - return nature; - } - - @Override - public MemberDetails getMember() { - return member; - } - - @Override - public String toString() { - return "AttributeMetadata(`" + name + "`)"; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/BasicKeyMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/BasicKeyMappingImpl.java deleted file mode 100644 index edbb21553e..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/BasicKeyMappingImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.BasicKeyMapping; - -/** - * @author Steve Ebersole - */ -public class BasicKeyMappingImpl implements BasicKeyMapping { - private final AttributeMetadata attribute; - - public BasicKeyMappingImpl(AttributeMetadata attribute) { - this.attribute = attribute; - } - - @Override - public AttributeMetadata getAttribute() { - return attribute; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizationHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizationHelper.java deleted file mode 100644 index f46399f411..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizationHelper.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.EnumSet; - -import org.hibernate.annotations.Any; -import org.hibernate.annotations.AnyDiscriminator; -import org.hibernate.annotations.AnyKeyJavaClass; -import org.hibernate.annotations.AnyKeyJavaType; -import org.hibernate.annotations.AnyKeyJdbcType; -import org.hibernate.annotations.AnyKeyJdbcTypeCode; -import org.hibernate.annotations.CompositeType; -import org.hibernate.annotations.EmbeddableInstantiator; -import org.hibernate.annotations.JavaType; -import org.hibernate.annotations.JdbcType; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.annotations.ManyToAny; -import org.hibernate.annotations.Nationalized; -import org.hibernate.annotations.TenantId; -import org.hibernate.annotations.TimeZoneColumn; -import org.hibernate.annotations.TimeZoneStorage; -import org.hibernate.annotations.Type; -import org.hibernate.boot.models.HibernateAnnotations; -import org.hibernate.boot.models.MultipleAttributeNaturesException; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.ClassAttributeAccessType; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; -import org.hibernate.models.spi.MemberDetails; - -import jakarta.persistence.Access; -import jakarta.persistence.AccessType; -import jakarta.persistence.Basic; -import jakarta.persistence.ElementCollection; -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import jakarta.persistence.EmbeddedId; -import jakarta.persistence.Entity; -import jakarta.persistence.Enumerated; -import jakarta.persistence.Lob; -import jakarta.persistence.ManyToMany; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.MappedSuperclass; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Temporal; -import jakarta.persistence.Version; - -import static org.hibernate.boot.models.categorize.ModelCategorizationLogging.MODEL_CATEGORIZATION_LOGGER; -import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.BASIC; -import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.ELEMENT_COLLECTION; -import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.EMBEDDED; -import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.MANY_TO_ANY; -import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.MANY_TO_MANY; -import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.ONE_TO_MANY; - -/** - * @author Steve Ebersole - */ -public class CategorizationHelper { - public static ClassDetails toClassDetails(Class clazz, ClassDetailsRegistry classDetailsRegistry) { - return classDetailsRegistry.resolveClassDetails( clazz.getName() ); - } - - public static boolean isMappedSuperclass(ClassDetails classDetails) { - return classDetails.hasDirectAnnotationUsage( MappedSuperclass.class ); - } - - public static boolean isEntity(ClassDetails classDetails) { - return classDetails.getDirectAnnotationUsage( Entity.class ) != null; - } - - public static boolean isIdentifiable(ClassDetails classDetails) { - return isEntity( classDetails ) || isMappedSuperclass( classDetails ); - } - - public static ClassAttributeAccessType determineAccessType(ClassDetails classDetails, AccessType implicitAccessType) { - final Access annotation = classDetails.getDirectAnnotationUsage( Access.class ); - if ( annotation != null ) { - final AccessType explicitValue = annotation.value(); - assert explicitValue != null; - return explicitValue == AccessType.FIELD - ? ClassAttributeAccessType.EXPLICIT_FIELD - : ClassAttributeAccessType.EXPLICIT_PROPERTY; - } - - return implicitAccessType == AccessType.FIELD - ? ClassAttributeAccessType.IMPLICIT_FIELD - : ClassAttributeAccessType.IMPLICIT_PROPERTY; - } - - /** - * Determine the attribute's nature - is it a basic mapping, an embeddable, ...? - *

- * Also performs some simple validation around multiple natures being indicated - */ - public static AttributeMetadata.AttributeNature determineAttributeNature(ClassDetails declarer, MemberDetails backingMember) { - final EnumSet natures = EnumSet.noneOf( AttributeMetadata.AttributeNature.class ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // first, look for explicit nature annotations - - final Any any = backingMember.getDirectAnnotationUsage( Any.class ); - final Basic basic = backingMember.getDirectAnnotationUsage( Basic.class ); - final ElementCollection elementCollection = backingMember.getDirectAnnotationUsage( ElementCollection.class ); - final Embedded embedded = backingMember.getDirectAnnotationUsage( Embedded.class ); - final EmbeddedId embeddedId = backingMember.getDirectAnnotationUsage( EmbeddedId.class ); - final ManyToAny manyToAny = backingMember.getDirectAnnotationUsage( ManyToAny.class ); - final ManyToMany manyToMany = backingMember.getDirectAnnotationUsage( ManyToMany.class ); - final ManyToOne manyToOne = backingMember.getDirectAnnotationUsage( ManyToOne.class ); - final OneToMany oneToMany = backingMember.getDirectAnnotationUsage( OneToMany.class ); - final OneToOne oneToOne = backingMember.getDirectAnnotationUsage( OneToOne.class ); - - if ( basic != null ) { - natures.add( AttributeMetadata.AttributeNature.BASIC ); - } - - if ( embedded != null - || embeddedId != null - || ( backingMember.getType() != null && backingMember.getType().determineRawClass().hasDirectAnnotationUsage( Embeddable.class ) ) ) { - natures.add( EMBEDDED ); - } - - if ( any != null ) { - natures.add( AttributeMetadata.AttributeNature.ANY ); - } - - if ( oneToOne != null || manyToOne != null ) { - natures.add( AttributeMetadata.AttributeNature.TO_ONE ); - } - - if ( elementCollection != null ) { - natures.add( ELEMENT_COLLECTION ); - } - - if ( oneToMany != null ) { - natures.add( ONE_TO_MANY ); - } - - if ( manyToMany != null ) { - natures.add( MANY_TO_MANY ); - } - - if ( manyToAny != null ) { - natures.add( MANY_TO_ANY ); - } - - // look at annotations that imply a nature - - final boolean plural = oneToMany != null - || manyToMany != null - || elementCollection != null - || manyToAny != null; - - final boolean implicitlyBasic = backingMember.hasDirectAnnotationUsage( Temporal.class ) - || backingMember.hasDirectAnnotationUsage( Lob.class ) - || backingMember.hasDirectAnnotationUsage( Enumerated.class ) - || backingMember.hasDirectAnnotationUsage( Version.class ) - || backingMember.hasDirectAnnotationUsage( HibernateAnnotations.GENERATED.getAnnotationType() ) - || backingMember.hasDirectAnnotationUsage( Nationalized.class ) - || backingMember.hasDirectAnnotationUsage( TimeZoneColumn.class ) - || backingMember.hasDirectAnnotationUsage( TimeZoneStorage.class ) - || backingMember.hasDirectAnnotationUsage( Type.class ) - || backingMember.hasDirectAnnotationUsage( TenantId.class ) - || backingMember.hasDirectAnnotationUsage( JavaType.class ) - || backingMember.hasDirectAnnotationUsage( JdbcType.class ) - || backingMember.hasDirectAnnotationUsage( JdbcTypeCode.class ); - - final boolean implicitlyEmbedded = backingMember.hasDirectAnnotationUsage( EmbeddableInstantiator.class ) - || backingMember.hasDirectAnnotationUsage( CompositeType.class ); - - final boolean implicitlyAny = backingMember.hasDirectAnnotationUsage( AnyDiscriminator.class ) -// || CollectionHelper.isNotEmpty( backingMember.getRepeatedAnnotationUsages( HibernateAnnotations.ANY_DISCRIMINATOR_VALUE ) ) -// || backingMember.hasDirectAnnotationUsage( HibernateAnnotations.ANY_DISCRIMINATOR_VALUES ) - || backingMember.hasDirectAnnotationUsage( AnyKeyJavaType.class ) - || backingMember.hasDirectAnnotationUsage( AnyKeyJavaClass.class ) - || backingMember.hasDirectAnnotationUsage( AnyKeyJdbcType.class ) - || backingMember.hasDirectAnnotationUsage( AnyKeyJdbcTypeCode.class ); - - if ( !plural ) { - // first implicit basic nature - if ( implicitlyBasic ) { - natures.add( AttributeMetadata.AttributeNature.BASIC ); - } - - // then embedded - if ( implicitlyEmbedded ) { - natures.add( EMBEDDED ); - } - - // and any - if ( implicitlyAny ) { - natures.add( AttributeMetadata.AttributeNature.ANY ); - } - } - else { - if ( elementCollection != null ) { - // for @ElementCollection, allow `@Basic` or `@Embedded` (though not both) - if ( natures.contains( BASIC ) ) { - if ( natures.contains( EMBEDDED ) ) { - // don't do anything, this is still an error - } - else { - MODEL_CATEGORIZATION_LOGGER.debugf( "Ignoring @Basic on @ElementCollection - %s", backingMember.resolveAttributeName() ); - natures.remove( BASIC ); - } - } - else if ( natures.contains( EMBEDDED ) ) { - MODEL_CATEGORIZATION_LOGGER.debugf( "Ignoring @Embedded on @ElementCollection - %s", backingMember.resolveAttributeName() ); - natures.remove( EMBEDDED ); - } - } - } - - int size = natures.size(); - return switch ( size ) { - case 0 -> { - MODEL_CATEGORIZATION_LOGGER.debugf( - "Implicitly interpreting attribute `%s` as BASIC", - backingMember.resolveAttributeName() - ); - yield AttributeMetadata.AttributeNature.BASIC; - } - case 1 -> natures.iterator().next(); - default -> throw new MultipleAttributeNaturesException( - declarer.getName() + "#" + backingMember.resolveAttributeName(), - natures - ); - }; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizedDomainModelImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizedDomainModelImpl.java deleted file mode 100644 index cd6335c9c9..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/CategorizedDomainModelImpl.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.Map; -import java.util.Set; - -import org.hibernate.boot.models.categorize.spi.CategorizedDomainModel; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.spi.GlobalRegistrations; -import org.hibernate.boot.models.xml.spi.PersistenceUnitMetadata; -import org.hibernate.models.spi.AnnotationDescriptorRegistry; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; - -/** - * @author Steve Ebersole - */ -public class CategorizedDomainModelImpl implements CategorizedDomainModel { - private final Set entityHierarchies; - private final Map mappedSuperclasses; - private final Map embeddables; - private final GlobalRegistrations globalRegistrations; - - private final ClassDetailsRegistry classDetailsRegistry; - private final AnnotationDescriptorRegistry annotationDescriptorRegistry; - private final PersistenceUnitMetadata persistenceUnitMetadata; - - public CategorizedDomainModelImpl( - ClassDetailsRegistry classDetailsRegistry, - AnnotationDescriptorRegistry annotationDescriptorRegistry, - PersistenceUnitMetadata persistenceUnitMetadata, - Set entityHierarchies, - Map mappedSuperclasses, - Map embeddables, - GlobalRegistrations globalRegistrations) { - this.classDetailsRegistry = classDetailsRegistry; - this.annotationDescriptorRegistry = annotationDescriptorRegistry; - this.persistenceUnitMetadata = persistenceUnitMetadata; - this.entityHierarchies = entityHierarchies; - this.mappedSuperclasses = mappedSuperclasses; - this.embeddables = embeddables; - this.globalRegistrations = globalRegistrations; - } - - @Override - public ClassDetailsRegistry getClassDetailsRegistry() { - return classDetailsRegistry; - } - - @Override - public AnnotationDescriptorRegistry getAnnotationDescriptorRegistry() { - return annotationDescriptorRegistry; - } - - @Override - public PersistenceUnitMetadata getPersistenceUnitMetadata() { - return persistenceUnitMetadata; - } - - @Override - public GlobalRegistrations getGlobalRegistrations() { - return globalRegistrations; - } - - @Override - public Set getEntityHierarchies() { - return entityHierarchies; - } - - public Map getMappedSuperclasses() { - return mappedSuperclasses; - } - - @Override - public Map getEmbeddables() { - return embeddables; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyBuilder.java deleted file mode 100644 index 428894049b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyBuilder.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.categorize.spi.IdentifiableTypeMetadata; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.models.spi.AnnotationTarget; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; -import org.hibernate.models.spi.FieldDetails; -import org.hibernate.models.spi.MethodDetails; - -import jakarta.persistence.Access; -import jakarta.persistence.AccessType; -import jakarta.persistence.EmbeddedId; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; - -/** - * Builds {@link EntityHierarchy} references from - * {@linkplain ClassDetailsRegistry#forEachClassDetails managed classes}. - * - * @author Steve Ebersole - */ -public class EntityHierarchyBuilder { - - /** - * Pre-processes the annotated entities from the index and create a set of entity hierarchies which can be bound - * to the metamodel. - * - * @param typeConsumer Callback for any identifiable-type metadata references - * @param buildingContext The table context, giving access to needed services and information - * - * @return a set of {@code EntityHierarchySource} instances. - */ - public static Set createEntityHierarchies( - Set rootEntities, - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext buildingContext) { - return new EntityHierarchyBuilder( buildingContext ).process( rootEntities, typeConsumer ); - } - - /** - * Pre-processes the annotated entities from the index and create a set of entity hierarchies which can be bound - * to the metamodel. - * - * @param typeConsumer Callback for any identifiable-type metadata references - * @param buildingContext The table context, giving access to needed services and information - * - * @return a set of {@code EntityHierarchySource} instances. - */ - public static Set createEntityHierarchies( - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext buildingContext) { - return createEntityHierarchies( - collectRootEntityTypes( buildingContext.getClassDetailsRegistry() ), - typeConsumer, - buildingContext - ); - } - - private final ModelCategorizationContext modelContext; - - public EntityHierarchyBuilder(ModelCategorizationContext modelContext) { - this.modelContext = modelContext; - } - - private Set process( - Set rootEntities, - HierarchyTypeConsumer typeConsumer) { - final Set hierarchies = CollectionHelper.setOfSize( rootEntities.size() ); - - rootEntities.forEach( (rootEntity) -> { - final AccessType defaultAccessType = determineDefaultAccessTypeForHierarchy( rootEntity ); - hierarchies.add( new EntityHierarchyImpl( - rootEntity, - defaultAccessType, - org.hibernate.cache.spi.access.AccessType.TRANSACTIONAL, - typeConsumer, - modelContext - ) ); - } ); - - return hierarchies; - } - - private AccessType determineDefaultAccessTypeForHierarchy(ClassDetails rootEntityType) { - assert rootEntityType != null; - -// // look for `@Access` at class level -// final AccessType classAnnotationValue = resolveDefaultAccessTypeFromClassAnnotation( rootEntityType ); -// if ( classAnnotationValue != null ) { -// return classAnnotationValue; -// } - - // look for `@Id` or `@EmbeddedId` - // todo (jpa32) : technically we could probably look for member with any "mapping" annotation - final AccessType accessFromAttribute = resolveDefaultAccessTypeFromMembers( rootEntityType ); - if ( accessFromAttribute != null ) { - return accessFromAttribute; - } - - -// // 2.3.1 Default Access Type -// // It is an error if a default access type cannot be determined and an access type is not explicitly specified -// // by means of annotations or the XML descriptor. -// throw new AccessTypeDeterminationException( rootEntityType ); - - return null; - } - - private AccessType resolveDefaultAccessTypeFromClassAnnotation(ClassDetails rootEntityType) { - ClassDetails current = rootEntityType; - while ( current != null ) { - final Access accessAnnotation = current.getDirectAnnotationUsage( Access.class ); - if ( accessAnnotation != null ) { - return accessAnnotation.value(); - } - - current = current.getSuperClass(); - } - - return null; - } - - private AccessType resolveDefaultAccessTypeFromMembers(ClassDetails rootEntityType) { - ClassDetails current = rootEntityType; - while ( current != null ) { - // look for `@Id` or `@EmbeddedId` (w/o `@Access`) - final AnnotationTarget idMember = determineIdMember( current ); - if ( idMember != null ) { - switch ( idMember.getKind() ) { - case FIELD: { - return AccessType.FIELD; - } - case METHOD: { - return AccessType.PROPERTY; - } - default: { - throw new IllegalStateException( "@Id / @EmbeddedId found on target other than field or method : " + idMember ); - } - } - } - - current = current.getSuperClass(); - } - - return null; - } - - private AnnotationTarget determineIdMember(ClassDetails current) { - final List methods = current.getMethods(); - for ( int i = 0; i < methods.size(); i++ ) { - final MethodDetails methodDetails = methods.get( i ); - if ( methodDetails.hasDirectAnnotationUsage( Id.class ) - || methodDetails.hasDirectAnnotationUsage( EmbeddedId.class ) ) { - if ( methodDetails.getDirectAnnotationUsage( Access.class ) == null ) { - return methodDetails; - } - } - } - - final List fields = current.getFields(); - for ( int i = 0; i < fields.size(); i++ ) { - final FieldDetails fieldDetails = fields.get( i ); - if ( fieldDetails.hasDirectAnnotationUsage( Id.class ) - || fieldDetails.hasDirectAnnotationUsage( EmbeddedId.class ) ) { - if ( fieldDetails.getDirectAnnotationUsage( Access.class ) == null ) { - return fieldDetails; - } - } - } - - return null; - } - - private Set collectRootEntityTypes() { - return collectRootEntityTypes( modelContext.getClassDetailsRegistry() ); - } - - private static Set collectRootEntityTypes(ClassDetailsRegistry classDetailsRegistry) { - final Set collectedTypes = new HashSet<>(); - - classDetailsRegistry.forEachClassDetails( (managedType) -> { - if ( managedType.getDirectAnnotationUsage( Entity.class ) != null - && isRoot( managedType ) ) { - collectedTypes.add( managedType ); - } - } ); - - return collectedTypes; - } - - public static boolean isRoot(ClassDetails classInfo) { - // perform a series of opt-out checks against the super-type hierarchy - - // an entity is considered a root of the hierarchy if: - // 1) it has no super-types - // 2) its super types contain no entities (MappedSuperclasses are allowed) - - if ( classInfo.getSuperClass() == null ) { - return true; - } - - ClassDetails current = classInfo.getSuperClass(); - while ( current != null ) { - if ( current.getDirectAnnotationUsage( Entity.class ) != null && !current.isAbstract() ) { - // a non-abstract super type has `@Entity` -> classInfo cannot be a root entity - return false; - } - current = current.getSuperClass(); - } - - // if we hit no opt-outs we have a root - return true; - } - - - /** - * Used in tests - */ - public static Set createEntityHierarchies(ModelCategorizationContext processingContext) { - return new EntityHierarchyBuilder( processingContext ).process( - collectRootEntityTypes( processingContext.getClassDetailsRegistry() ), - EntityHierarchyBuilder::ignore - ); - } - - private static void ignore(IdentifiableTypeMetadata it) {} -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyImpl.java deleted file mode 100644 index 63f3056116..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityHierarchyImpl.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.Locale; - -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.NaturalIdCache; -import org.hibernate.annotations.OptimisticLockType; -import org.hibernate.annotations.OptimisticLocking; -import org.hibernate.boot.models.categorize.ModelCategorizationLogging; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.CacheRegion; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata; -import org.hibernate.boot.models.categorize.spi.IdentifiableTypeMetadata; -import org.hibernate.boot.models.categorize.spi.KeyMapping; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.boot.models.categorize.spi.NaturalIdCacheRegion; -import org.hibernate.cache.spi.access.AccessType; -import org.hibernate.engine.OptimisticLockStyle; -import org.hibernate.models.spi.ClassDetails; - -import jakarta.persistence.Inheritance; -import jakarta.persistence.InheritanceType; - -/** - * - * @author Steve Ebersole - */ -public class EntityHierarchyImpl implements EntityHierarchy { - private final IdentifiableTypeMetadata absoluteRootTypeMetadata; - private final EntityTypeMetadata rootEntityTypeMetadata; - - private final InheritanceType inheritanceType; - private final jakarta.persistence.AccessType defaultAccessType; - private final OptimisticLockStyle optimisticLockStyle; - - private final KeyMapping idMapping; - private final KeyMapping naturalIdMapping; - private final AttributeMetadata versionAttribute; - private final AttributeMetadata tenantIdAttribute; - - private final CacheRegion cacheRegion; - private final NaturalIdCacheRegion naturalIdCacheRegion; - - public EntityHierarchyImpl( - ClassDetails rootEntityClassDetails, - jakarta.persistence.AccessType defaultAccessType, - AccessType defaultCacheAccessType, - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext categorizationContext) { - this.defaultAccessType = defaultAccessType; - - final ClassDetails absoluteRootClassDetails = findRootRoot( rootEntityClassDetails ); - final HierarchyMetadataCollector metadataCollector = new HierarchyMetadataCollector( - this, - rootEntityClassDetails, - typeConsumer, - categorizationContext - ); - - if ( CategorizationHelper.isEntity( absoluteRootClassDetails ) ) { - this.rootEntityTypeMetadata = new EntityTypeMetadataImpl( - absoluteRootClassDetails, - this, - defaultAccessType, - metadataCollector, - categorizationContext - ); - this.absoluteRootTypeMetadata = rootEntityTypeMetadata; - } - else { - assert CategorizationHelper.isMappedSuperclass( absoluteRootClassDetails ); - this.absoluteRootTypeMetadata = processRootMappedSuperclasses( - absoluteRootClassDetails, - this, - defaultAccessType, - metadataCollector, - categorizationContext - ); - this.rootEntityTypeMetadata = new EntityTypeMetadataImpl( - rootEntityClassDetails, - this, - (AbstractIdentifiableTypeMetadata) absoluteRootTypeMetadata, - metadataCollector, - categorizationContext - ); - } - - this.inheritanceType = determineInheritanceType( metadataCollector ); - this.optimisticLockStyle = determineOptimisticLockStyle( metadataCollector ); - - this.idMapping = metadataCollector.getIdMapping(); - this.naturalIdMapping = metadataCollector.getNaturalIdMapping(); - this.versionAttribute = metadataCollector.getVersionAttribute(); - this.tenantIdAttribute = metadataCollector.getTenantIdAttribute(); - - this.cacheRegion = determineCacheRegion( metadataCollector, defaultCacheAccessType ); - this.naturalIdCacheRegion = determineNaturalIdCacheRegion( metadataCollector, cacheRegion ); - } - - private static IdentifiableTypeMetadata processRootMappedSuperclasses( - ClassDetails absoluteRootClassDetails, - EntityHierarchyImpl entityHierarchy, - jakarta.persistence.AccessType defaultAccessType, - HierarchyMetadataCollector metadataCollector, - ModelCategorizationContext modelBuildingContext) { - return new MappedSuperclassTypeMetadataImpl( - absoluteRootClassDetails, - entityHierarchy, - null, - defaultAccessType, - metadataCollector, - modelBuildingContext - ); - } - - private ClassDetails findRootRoot(ClassDetails rootEntityClassDetails) { - if ( rootEntityClassDetails.getSuperClass() != null ) { - final ClassDetails match = walkSupers( rootEntityClassDetails.getSuperClass() ); - if ( match != null ) { - return match; - } - } - return rootEntityClassDetails; - } - - private ClassDetails walkSupers(ClassDetails type) { - assert type != null; - - if ( type.getSuperClass() != null ) { - final ClassDetails match = walkSupers( type.getSuperClass() ); - if ( match != null ) { - return match; - } - } - - if ( CategorizationHelper.isIdentifiable( type ) ) { - return type; - } - - return null; - } - - @Override - public EntityTypeMetadata getRoot() { - return rootEntityTypeMetadata; - } - - @Override - public IdentifiableTypeMetadata getAbsoluteRoot() { - return absoluteRootTypeMetadata; - } - - @Override - public InheritanceType getInheritanceType() { - return inheritanceType; - } - - @Override - public jakarta.persistence.AccessType getDefaultAccessType() { - return defaultAccessType; - } - - @Override - public KeyMapping getIdMapping() { - return idMapping; - } - - @Override - public KeyMapping getNaturalIdMapping() { - return naturalIdMapping; - } - - @Override - public AttributeMetadata getVersionAttribute() { - return versionAttribute; - } - - @Override - public AttributeMetadata getTenantIdAttribute() { - return tenantIdAttribute; - } - - @Override - public OptimisticLockStyle getOptimisticLockStyle() { - return optimisticLockStyle; - } - - @Override - public CacheRegion getCacheRegion() { - return cacheRegion; - } - - @Override - public NaturalIdCacheRegion getNaturalIdCacheRegion() { - return naturalIdCacheRegion; - } - - @Override - public void forEachType(HierarchyTypeVisitor typeVisitor) { - final IdentifiableTypeMetadata absoluteRoot = getAbsoluteRoot(); - final HierarchyRelation hierarchyRelation; - if ( absoluteRoot == getRoot() ) { - hierarchyRelation = HierarchyRelation.ROOT; - } - else { - hierarchyRelation = HierarchyRelation.SUPER; - } - - forEachType( absoluteRoot, null, hierarchyRelation, typeVisitor ); - } - - private void forEachType( - IdentifiableTypeMetadata type, - IdentifiableTypeMetadata superType, - HierarchyRelation hierarchyRelation, - HierarchyTypeVisitor typeVisitor) { - typeVisitor.visitType( type, superType, this, hierarchyRelation ); - - final HierarchyRelation nextRelation; - if ( hierarchyRelation == HierarchyRelation.SUPER ) { - if ( type == getRoot().getSuperType() ) { - // the next iteration will be the root - nextRelation = HierarchyRelation.ROOT; - } - else { - nextRelation = HierarchyRelation.SUPER; - } - } - else { - nextRelation = HierarchyRelation.SUB; - } - - type.forEachSubType( subType -> forEachType( subType, type, nextRelation, typeVisitor ) ); - } - - @Override - public String toString() { - return String.format( - Locale.ROOT, - "EntityHierarchy(`%s` (%s))", - rootEntityTypeMetadata.getEntityName(), - inheritanceType.name() - ); - } - - - private static final OptimisticLockStyle DEFAULT_LOCKING_STRATEGY = OptimisticLockStyle.VERSION; - - private InheritanceType determineInheritanceType(HierarchyMetadataCollector metadataCollector) { - if ( ModelCategorizationLogging.MODEL_CATEGORIZATION_LOGGER.isDebugEnabled() ) { - // Validate that there is no @Inheritance annotation further down the hierarchy - ensureNoInheritanceAnnotationsOnSubclasses( rootEntityTypeMetadata ); - } - - final Inheritance inheritanceAnnotation = metadataCollector.getInheritanceAnnotation(); - if ( inheritanceAnnotation != null ) { - return inheritanceAnnotation.strategy(); - } - - return InheritanceType.SINGLE_TABLE; - } - - private OptimisticLockStyle determineOptimisticLockStyle(HierarchyMetadataCollector metadataCollector) { - final OptimisticLocking optimisticLockingAnnotation = metadataCollector.getOptimisticLockingAnnotation(); - if ( optimisticLockingAnnotation != null ) { - final OptimisticLockType lockingType = optimisticLockingAnnotation.type(); - return OptimisticLockStyle.fromLockType( lockingType ); - } - return DEFAULT_LOCKING_STRATEGY; - } - - private CacheRegion determineCacheRegion( - HierarchyMetadataCollector metadataCollector, - AccessType defaultCacheAccessType) { - final Cache cacheAnnotation = metadataCollector.getCacheAnnotation(); - return new CacheRegion( cacheAnnotation, defaultCacheAccessType, rootEntityTypeMetadata.getEntityName() ); - } - - private NaturalIdCacheRegion determineNaturalIdCacheRegion( - HierarchyMetadataCollector metadataCollector, - CacheRegion cacheRegion) { - final NaturalIdCache naturalIdCacheAnnotation = metadataCollector.getNaturalIdCacheAnnotation(); - return new NaturalIdCacheRegion( naturalIdCacheAnnotation, cacheRegion ); - } - - /** - * Find the InheritanceType from the locally defined {@link Inheritance} annotation, - * if one. Returns {@code null} if {@link Inheritance} is not locally defined. - * - * @apiNote Used when building the {@link EntityHierarchy} - */ - private static InheritanceType getLocallyDefinedInheritanceType(ClassDetails managedClass) { - final Inheritance localAnnotation = managedClass.getDirectAnnotationUsage( Inheritance.class ); - if ( localAnnotation == null ) { - return null; - } - - return localAnnotation.strategy(); - } - - private void ensureNoInheritanceAnnotationsOnSubclasses(IdentifiableTypeMetadata type) { - type.forEachSubType( (subType) -> { - if ( getLocallyDefinedInheritanceType( subType.getClassDetails() ) != null ) { - ModelCategorizationLogging.MODEL_CATEGORIZATION_LOGGER.debugf( - "@javax.persistence.Inheritance was specified on non-root entity [%s]; ignoring...", - type.getClassDetails().getName() - ); - } - ensureNoInheritanceAnnotationsOnSubclasses( subType ); - } ); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityTypeMetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityTypeMetadataImpl.java deleted file mode 100644 index 03aa4a33fb..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityTypeMetadataImpl.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.lang.annotation.Annotation; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.hibernate.annotations.BatchSize; -import org.hibernate.annotations.DynamicInsert; -import org.hibernate.annotations.DynamicUpdate; -import org.hibernate.annotations.Immutable; -import org.hibernate.annotations.ResultCheckStyle; -import org.hibernate.annotations.SQLDelete; -import org.hibernate.annotations.SQLInsert; -import org.hibernate.annotations.SQLUpdate; -import org.hibernate.annotations.Synchronize; -import org.hibernate.boot.model.CustomSql; -import org.hibernate.boot.model.naming.EntityNaming; -import org.hibernate.boot.models.annotations.spi.CustomSqlDetails; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; -import org.hibernate.internal.util.collections.ArrayHelper; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.models.spi.ClassDetails; - -import jakarta.persistence.AccessType; -import jakarta.persistence.Cacheable; -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; - -import static org.hibernate.internal.util.StringHelper.EMPTY_STRINGS; -import static org.hibernate.internal.util.StringHelper.isNotEmpty; -import static org.hibernate.internal.util.StringHelper.unqualify; - -/** - * @author Steve Ebersole - */ -public class EntityTypeMetadataImpl - extends AbstractIdentifiableTypeMetadata - implements EntityTypeMetadata, EntityNaming { - private final String entityName; - private final String jpaEntityName; - - private final List attributeList; - - private final boolean mutable; - private final boolean cacheable; - private final boolean isLazy; - private final String proxy; - private final int batchSize; - private final String discriminatorMatchValue; - private final boolean isDynamicInsert; - private final boolean isDynamicUpdate; - private final Map customInsertMap; - private final Map customUpdateMap; - private final Map customDeleteMap; - private final String[] synchronizedTableNames; - - private List hierarchyEventListeners; - private List completeEventListeners; - - /** - * Form used when the entity is the absolute-root (no mapped-super) of the hierarchy - */ - public EntityTypeMetadataImpl( - ClassDetails classDetails, - EntityHierarchy hierarchy, - AccessType defaultAccessType, - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext modelContext) { - super( classDetails, hierarchy, null, defaultAccessType, modelContext ); - - // NOTE: There is no annotation for `entity-name` - it comes exclusively from XML - // mappings. By default, the `entityName` is simply the entity class name. - // `ClassDetails#getName` already handles this all for us - this.entityName = getClassDetails().getName(); - - final Entity entityAnnotation = classDetails.getDirectAnnotationUsage( Entity.class ); - this.jpaEntityName = determineJpaEntityName( entityAnnotation, entityName ); - - final LifecycleCallbackCollector lifecycleCallbackCollector = new LifecycleCallbackCollector( classDetails, modelContext ); - this.attributeList = resolveAttributes( lifecycleCallbackCollector ); - this.hierarchyEventListeners = collectHierarchyEventListeners( lifecycleCallbackCollector.resolve() ); - this.completeEventListeners = collectCompleteEventListeners( modelContext ); - - this.mutable = determineMutability( classDetails, modelContext ); - this.cacheable = determineCacheability( classDetails, modelContext ); - this.synchronizedTableNames = determineSynchronizedTableNames(); - this.batchSize = determineBatchSize(); - this.isDynamicInsert = decodeDynamicInsert(); - this.isDynamicUpdate = decodeDynamicUpdate(); - this.customInsertMap = extractCustomSql( classDetails, SQLInsert.class ); - this.customUpdateMap = extractCustomSql( classDetails, SQLUpdate.class ); - this.customDeleteMap = extractCustomSql( classDetails, SQLDelete.class ); - - // defaults are that it is lazy and that the class itself is the proxy class - this.isLazy = true; - this.proxy = getEntityName(); - - final DiscriminatorValue discriminatorValueAnn = classDetails.getDirectAnnotationUsage( DiscriminatorValue.class ); - if ( discriminatorValueAnn != null ) { - this.discriminatorMatchValue = discriminatorValueAnn.value(); - } - else { - this.discriminatorMatchValue = null; - } - - postInstantiate( true, typeConsumer ); - } - - /** - * Form used when the entity is NOT the absolute-root of the hierarchy - */ - public EntityTypeMetadataImpl( - ClassDetails classDetails, - EntityHierarchy hierarchy, - AbstractIdentifiableTypeMetadata superType, - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext modelContext) { - super( classDetails, hierarchy, superType, modelContext ); - - // NOTE: There is no annotation for `entity-name` - it comes exclusively from XML - // mappings. By default, the `entityName` is simply the entity class name. - // `ClassDetails#getName` already handles this all for us - this.entityName = getClassDetails().getName(); - - final Entity entityAnnotation = classDetails.getDirectAnnotationUsage( Entity.class ); - this.jpaEntityName = determineJpaEntityName( entityAnnotation, entityName ); - - final LifecycleCallbackCollector lifecycleCallbackCollector = new LifecycleCallbackCollector( classDetails, modelContext ); - this.attributeList = resolveAttributes( lifecycleCallbackCollector ); - this.hierarchyEventListeners = collectHierarchyEventListeners( lifecycleCallbackCollector.resolve() ); - this.completeEventListeners = collectCompleteEventListeners( modelContext ); - - this.mutable = determineMutability( classDetails, modelContext ); - this.cacheable = determineCacheability( classDetails, modelContext ); - this.synchronizedTableNames = determineSynchronizedTableNames(); - this.batchSize = determineBatchSize(); - this.isDynamicInsert = decodeDynamicInsert(); - this.isDynamicUpdate = decodeDynamicUpdate(); - this.customInsertMap = extractCustomSql( classDetails, SQLInsert.class ); - this.customUpdateMap = extractCustomSql( classDetails, SQLUpdate.class ); - this.customDeleteMap = extractCustomSql( classDetails, SQLDelete.class ); - - // defaults are that it is lazy and that the class itself is the proxy class - this.isLazy = true; - this.proxy = getEntityName(); - - final DiscriminatorValue discriminatorValueAnn = classDetails.getDirectAnnotationUsage( DiscriminatorValue.class ); - if ( discriminatorValueAnn != null ) { - this.discriminatorMatchValue = discriminatorValueAnn.value(); - } - else { - this.discriminatorMatchValue = null; - } - - postInstantiate( true, typeConsumer ); - } - - @Override - protected List attributeList() { - return attributeList; - } - - @Override - public String getEntityName() { - return entityName; - } - - @Override - public String getJpaEntityName() { - return jpaEntityName; - } - - @Override - public String getClassName() { - return getClassDetails().getClassName(); - } - - @Override - public boolean isMutable() { - return mutable; - } - - @Override - public boolean isCacheable() { - return cacheable; - } - - @Override - public String[] getSynchronizedTableNames() { - return synchronizedTableNames; - } - - @Override - public int getBatchSize() { - return batchSize; - } - - @Override - public boolean isDynamicInsert() { - return isDynamicInsert; - } - - @Override - public boolean isDynamicUpdate() { - return isDynamicUpdate; - } - - @Override - public Map getCustomInserts() { - return customInsertMap; - } - - @Override - public Map getCustomUpdates() { - return customUpdateMap; - } - - @Override - public Map getCustomDeletes() { - return customDeleteMap; - } - - public String getDiscriminatorMatchValue() { - return discriminatorMatchValue; - } - - public boolean isLazy() { - return isLazy; - } - - public String getProxy() { - return proxy; - } - - @Override - public List getHierarchyJpaEventListeners() { - return hierarchyEventListeners; - } - - @Override - public List getCompleteJpaEventListeners() { - return completeEventListeners; - } - - - private String determineJpaEntityName(Entity entityAnnotation, String entityName) { - final String name = entityAnnotation.name(); - if ( isNotEmpty( name ) ) { - return name; - } - return unqualify( entityName ); - } - - private boolean determineMutability(ClassDetails classDetails, ModelCategorizationContext modelContext) { - final Immutable immutableAnn = classDetails.getDirectAnnotationUsage( Immutable.class ); - return immutableAnn == null; - } - - private boolean determineCacheability( - ClassDetails classDetails, - ModelCategorizationContext modelContext) { - final Cacheable cacheableAnn = classDetails.getDirectAnnotationUsage( Cacheable.class ); - switch ( modelContext.getSharedCacheMode() ) { - case NONE: { - return false; - } - case ALL: { - return true; - } - case DISABLE_SELECTIVE: { - // Disable caching for all `@Cacheable(false)`, enabled otherwise (including no annotation) - //noinspection RedundantIfStatement - if ( cacheableAnn == null || cacheableAnn.value() ) { - // not disabled - return true; - } - else { - // disable, there was an explicit `@Cacheable(false)` - return false; - } - } - default: { - // ENABLE_SELECTIVE - // UNSPECIFIED - - // Enable caching for all `@Cacheable(true)`, disable otherwise (including no annotation) - //noinspection RedundantIfStatement - if ( cacheableAnn != null && cacheableAnn.value() ) { - // enable, there was an explicit `@Cacheable(true)` - return true; - } - else { - return false; - } - } - } - } - - /** - * Build a CustomSql reference from {@link SQLInsert}, - * {@link SQLUpdate}, {@link SQLDelete} - * or {@link org.hibernate.annotations.SQLDeleteAll} annotations - */ - public static
Map extractCustomSql(ClassDetails classDetails, Class annotationType) { - final A[] annotationUsages = classDetails.getRepeatedAnnotationUsages( annotationType, null ); - if ( CollectionHelper.isEmpty( annotationUsages ) ) { - return Collections.emptyMap(); - } - - final Map result = new HashMap<>(); - ArrayHelper.forEach( annotationUsages, (customSqlAnnotation) -> { - final CustomSqlDetails customSqlDetails = (CustomSqlDetails) customSqlAnnotation; - final String sql = customSqlDetails.sql(); - final boolean isCallable = customSqlDetails.callable(); - - final ResultCheckStyle checkValue = customSqlDetails.check(); - final ExecuteUpdateResultCheckStyle checkStyle; - if ( checkValue == null ) { - checkStyle = isCallable - ? ExecuteUpdateResultCheckStyle.NONE - : ExecuteUpdateResultCheckStyle.COUNT; - } - else { - checkStyle = ExecuteUpdateResultCheckStyle.fromResultCheckStyle( checkValue ); - } - - result.put( - customSqlDetails.table(), - new CustomSql( sql, isCallable, checkStyle ) - ); - } ); - return result; - } - - private String[] determineSynchronizedTableNames() { - final Synchronize synchronizeAnnotation = getClassDetails().getDirectAnnotationUsage( Synchronize.class ); - if ( synchronizeAnnotation != null ) { - return synchronizeAnnotation.value(); - } - return EMPTY_STRINGS; - } - - private int determineBatchSize() { - final BatchSize batchSizeAnnotation = getClassDetails().getDirectAnnotationUsage( BatchSize.class ); - if ( batchSizeAnnotation != null ) { - return batchSizeAnnotation.size(); - } - return -1; - } - - private boolean decodeDynamicInsert() { - return getClassDetails().getDirectAnnotationUsage( DynamicInsert.class ) != null; - } - - private boolean decodeDynamicUpdate() { - return getClassDetails().getDirectAnnotationUsage( DynamicUpdate.class ) != null; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyMetadataCollector.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyMetadataCollector.java deleted file mode 100644 index a9ead35d56..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyMetadataCollector.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import org.hibernate.AnnotationException; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.NaturalId; -import org.hibernate.annotations.NaturalIdCache; -import org.hibernate.annotations.OptimisticLocking; -import org.hibernate.annotations.TenantId; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata; -import org.hibernate.boot.models.categorize.spi.IdentifiableTypeMetadata; -import org.hibernate.boot.models.categorize.spi.KeyMapping; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.models.ModelsException; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.MemberDetails; - -import jakarta.persistence.EmbeddedId; -import jakarta.persistence.Id; -import jakarta.persistence.IdClass; -import jakarta.persistence.Inheritance; -import jakarta.persistence.Version; - -/** - * Used to collect useful details about a hierarchy as we build its metadata - * - * @implNote The HierarchyTypeConsumer is called from root down. We make use - * of that detail in a number of places here in the code. - * - * @author Steve Ebersole - */ -public class HierarchyMetadataCollector implements HierarchyTypeConsumer { - private final EntityHierarchy entityHierarchy; - private final ClassDetails rootEntityClassDetails; - private final HierarchyTypeConsumer delegateConsumer; - private final ModelCategorizationContext categorizationContext; - - private boolean belowRootEntity; - - private EntityTypeMetadata rootEntityMetadata; - private Inheritance inheritanceAnnotation; - private OptimisticLocking optimisticLockingAnnotation; - private Cache cacheAnnotation; - private NaturalIdCache naturalIdCacheAnnotation; - - private KeyMapping idMapping; - private AttributeMetadata versionAttribute; - private AttributeMetadata tenantIdAttribute; - - private IdClass idClassAnnotation; - private Object collectedIdAttributes; - private Object collectedNaturalIdAttributes; - - public HierarchyMetadataCollector( - EntityHierarchy entityHierarchy, - ClassDetails rootEntityClassDetails, - HierarchyTypeConsumer delegateConsumer, - ModelCategorizationContext categorizationContext) { - this.entityHierarchy = entityHierarchy; - this.rootEntityClassDetails = rootEntityClassDetails; - this.delegateConsumer = delegateConsumer; - this.categorizationContext = categorizationContext; - } - - public EntityTypeMetadata getRootEntityMetadata() { - return rootEntityMetadata; - } - - public KeyMapping getIdMapping() { - if ( idMapping == null ) { - idMapping = buildIdMapping(); - } - - return idMapping; - } - - public Inheritance getInheritanceAnnotation() { - return inheritanceAnnotation; - } - - public AttributeMetadata getVersionAttribute() { - return versionAttribute; - } - - public AttributeMetadata getTenantIdAttribute() { - return tenantIdAttribute; - } - - public OptimisticLocking getOptimisticLockingAnnotation() { - return optimisticLockingAnnotation; - } - - public Cache getCacheAnnotation() { - return cacheAnnotation; - } - - public NaturalIdCache getNaturalIdCacheAnnotation() { - return naturalIdCacheAnnotation; - } - - private KeyMapping buildIdMapping() { - if ( collectedIdAttributes == null ) { - throw new AnnotationException( "Unable to determine id attribute(s) - " + rootEntityClassDetails.getName() ); - } - - if ( collectedIdAttributes instanceof List ) { - //noinspection unchecked - final List idAttributes = (List) collectedIdAttributes; - final ClassDetails idClassDetails; - if ( idClassAnnotation == null ) { - idClassDetails = null; - } - else { - idClassDetails = toClassDetails( idClassAnnotation.value() ); - } - return new NonAggregatedKeyMappingImpl( idAttributes, idClassDetails ); - } - - final AttributeMetadata idAttribute = (AttributeMetadata) collectedIdAttributes; - - if ( idAttribute.getNature() == AttributeMetadata.AttributeNature.BASIC ) { - return new BasicKeyMappingImpl( idAttribute ); - } - - if ( idAttribute.getNature() == AttributeMetadata.AttributeNature.EMBEDDED ) { - return new AggregatedKeyMappingImpl( idAttribute ); - } - - if ( idAttribute.getNature() == AttributeMetadata.AttributeNature.TO_ONE ) { - final List idAttributes = List.of( idAttribute ); - final ClassDetails idClassDetails; - if ( idClassAnnotation == null ) { - idClassDetails = null; - } - else { - idClassDetails = toClassDetails( idClassAnnotation.value() ); - } - return new NonAggregatedKeyMappingImpl( idAttributes, idClassDetails ); - } - - throw new ModelsException( - String.format( - Locale.ROOT, - "Unexpected attribute nature [%s] - %s", - idAttribute.getNature(), - entityHierarchy.getRoot().getEntityName() - ) - ); - } - - private ClassDetails toClassDetails(Class value) { - if ( value == null ) { - return null; - } - return categorizationContext.getClassDetailsRegistry().getClassDetails( value.getName() ); - } - - public KeyMapping getNaturalIdMapping() { - if ( collectedNaturalIdAttributes == null ) { - return null; - } - - if ( collectedNaturalIdAttributes instanceof List ) { - //noinspection unchecked - final List attributes = (List) collectedNaturalIdAttributes; - return new NonAggregatedKeyMappingImpl( attributes, null ); - } - - final AttributeMetadata attribute = (AttributeMetadata) collectedNaturalIdAttributes; - - if ( attribute.getNature() == AttributeMetadata.AttributeNature.BASIC ) { - return new BasicKeyMappingImpl( attribute ); - } - - if ( attribute.getNature() == AttributeMetadata.AttributeNature.EMBEDDED ) { - return new AggregatedKeyMappingImpl( attribute ); - } - - if ( attribute.getNature() == AttributeMetadata.AttributeNature.TO_ONE ) { - return new BasicKeyMappingImpl( attribute ); - } - - throw new ModelsException( - String.format( - Locale.ROOT, - "Unexpected attribute nature [%s] - %s", - attribute.getNature(), - entityHierarchy.getRoot().getEntityName() - ) - ); - } - - @Override - public void acceptType(IdentifiableTypeMetadata typeMetadata) { - if ( delegateConsumer != null ) { - delegateConsumer.acceptType( typeMetadata ); - } - - if ( belowRootEntity ) { - return; - } - - final ClassDetails classDetails = typeMetadata.getClassDetails(); - - if ( classDetails == rootEntityClassDetails ) { - rootEntityMetadata = (EntityTypeMetadata) typeMetadata; - belowRootEntity = true; - } - - inheritanceAnnotation = applyLocalAnnotation( Inheritance.class, classDetails, inheritanceAnnotation ); - optimisticLockingAnnotation = applyLocalAnnotation( OptimisticLocking.class, classDetails, optimisticLockingAnnotation ); - cacheAnnotation = applyLocalAnnotation( Cache.class, classDetails, cacheAnnotation ); - naturalIdCacheAnnotation = applyLocalAnnotation( NaturalIdCache.class, classDetails, naturalIdCacheAnnotation ); - idClassAnnotation = applyLocalAnnotation( IdClass.class, classDetails, idClassAnnotation ); - - final boolean collectIds = collectedIdAttributes == null; - if ( collectIds || versionAttribute == null || tenantIdAttribute == null ) { - // walk the attributes - typeMetadata.forEachAttribute( (index, attributeMetadata) -> { - final MemberDetails attributeMember = attributeMetadata.getMember(); - - if ( collectIds ) { - final EmbeddedId eIdAnn = attributeMember.getDirectAnnotationUsage( EmbeddedId.class ); - if ( eIdAnn != null ) { - collectIdAttribute( attributeMetadata ); - } - - final Id idAnn = attributeMember.getDirectAnnotationUsage( Id.class ); - if ( idAnn != null ) { - collectIdAttribute( attributeMetadata ); - } - } - - if ( attributeMember.getDirectAnnotationUsage( NaturalId.class ) != null ) { - collectNaturalIdAttribute( attributeMetadata ); - } - - if ( versionAttribute == null ) { - if ( attributeMember.getDirectAnnotationUsage( Version.class ) != null ) { - versionAttribute = attributeMetadata; - } - } - - if ( tenantIdAttribute == null ) { - if ( attributeMember.getDirectAnnotationUsage( TenantId.class ) != null ) { - tenantIdAttribute = attributeMetadata; - } - } - } ); - } - } - - private A applyLocalAnnotation(Class annotationType, ClassDetails classDetails, A currentValue) { - final A localInheritanceAnnotation = classDetails.getDirectAnnotationUsage( annotationType ); - if ( localInheritanceAnnotation != null ) { - // the one "closest" to the root-entity should win - return localInheritanceAnnotation; - } - - return currentValue; - } - - public void collectIdAttribute(AttributeMetadata member) { - assert member != null; - - if ( collectedIdAttributes == null ) { - collectedIdAttributes = member; - } - else if ( collectedIdAttributes instanceof List ) { - //noinspection unchecked,rawtypes - final List membersList = (List) collectedIdAttributes; - membersList.add( member ); - } - else if ( collectedIdAttributes instanceof AttributeMetadata ) { - final ArrayList combined = new ArrayList<>(); - combined.add( (AttributeMetadata) collectedIdAttributes ); - combined.add( member ); - collectedIdAttributes = combined; - } - } - - public void collectNaturalIdAttribute(AttributeMetadata member) { - assert member != null; - - if ( collectedNaturalIdAttributes == null ) { - collectedNaturalIdAttributes = member; - } - else if ( collectedNaturalIdAttributes instanceof List ) { - //noinspection unchecked,rawtypes - final List membersList = (List) collectedNaturalIdAttributes; - membersList.add( member ); - } - else if ( collectedNaturalIdAttributes instanceof AttributeMetadata ) { - final ArrayList combined = new ArrayList<>(); - combined.add( (AttributeMetadata) collectedNaturalIdAttributes ); - combined.add( member ); - collectedNaturalIdAttributes = combined; - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyTypeConsumer.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyTypeConsumer.java deleted file mode 100644 index a65f39092f..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/HierarchyTypeConsumer.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import org.hibernate.boot.models.categorize.spi.IdentifiableTypeMetadata; - -/** - * Consumer of types as we walk the managed-type hierarchy - * - * @author Steve Ebersole - */ -@FunctionalInterface -public interface HierarchyTypeConsumer { - void acceptType(IdentifiableTypeMetadata type); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/LifecycleCallbackCollector.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/LifecycleCallbackCollector.java deleted file mode 100644 index b271f72da7..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/LifecycleCallbackCollector.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.lang.annotation.Annotation; -import java.util.Locale; - -import org.hibernate.boot.models.categorize.spi.AllMemberConsumer; -import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.models.ModelsException; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.MemberDetails; -import org.hibernate.models.spi.MethodDetails; - -import jakarta.persistence.PostLoad; -import jakarta.persistence.PostPersist; -import jakarta.persistence.PostRemove; -import jakarta.persistence.PostUpdate; -import jakarta.persistence.PrePersist; -import jakarta.persistence.PreRemove; -import jakarta.persistence.PreUpdate; - -import static org.hibernate.boot.models.spi.JpaEventListener.matchesSignature; - -/** - * @author Steve Ebersole - */ -public class LifecycleCallbackCollector implements AllMemberConsumer { - private final ClassDetails managedTypeDetails; - private final ModelCategorizationContext modelContext; - - private MethodDetails prePersist; - private MethodDetails postPersist; - private MethodDetails preUpdate; - private MethodDetails postUpdate; - private MethodDetails preRemove; - private MethodDetails postRemove; - private MethodDetails postLoad; - - public LifecycleCallbackCollector(ClassDetails managedTypeDetails, ModelCategorizationContext modelContext) { - this.managedTypeDetails = managedTypeDetails; - this.modelContext = modelContext; - } - - @Override - public void acceptMember(MemberDetails memberDetails) { - if ( memberDetails.isField() ) { - return; - } - - final MethodDetails methodDetails = (MethodDetails) memberDetails; - - if ( methodDetails.hasDirectAnnotationUsage( PrePersist.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - prePersist = apply( methodDetails, PrePersist.class, managedTypeDetails, prePersist ); - } - else if ( methodDetails.hasDirectAnnotationUsage( PostPersist.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - postPersist = apply( methodDetails, PostPersist.class, managedTypeDetails, postPersist ); - } - else if ( methodDetails.hasDirectAnnotationUsage( PreRemove.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - preRemove = apply( methodDetails, PreRemove.class, managedTypeDetails, preRemove ); - } - else if ( methodDetails.hasDirectAnnotationUsage( PostRemove.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - postRemove = apply( methodDetails, PostRemove.class, managedTypeDetails, postRemove ); - } - else if ( methodDetails.hasDirectAnnotationUsage( PreUpdate.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - preUpdate = apply( methodDetails, PreUpdate.class, managedTypeDetails, preUpdate ); - } - else if ( methodDetails.hasDirectAnnotationUsage( PostUpdate.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - postUpdate = apply( methodDetails, PostUpdate.class, managedTypeDetails, postUpdate ); - } - else if ( methodDetails.hasDirectAnnotationUsage( PostLoad.class ) - && matchesSignature( JpaEventListenerStyle.CALLBACK, methodDetails ) ) { - postLoad = apply( methodDetails, PostLoad.class, managedTypeDetails, postLoad ); - } - } - - private static MethodDetails apply( - MethodDetails incomingValue, - Class annotationType, - ClassDetails managedTypeDetails, - MethodDetails currentValue) { - if ( currentValue != null ) { - throw new ModelsException( - String.format( - Locale.ROOT, - "Encountered multiple @%s methods [%s] - %s, %s", - annotationType.getSimpleName(), - managedTypeDetails.getClassName(), - currentValue.getName(), - incomingValue.getName() - ) - ); - } - return incomingValue; - } - - public JpaEventListener resolve() { - if ( prePersist != null - || postPersist != null - || preUpdate != null - || postUpdate != null - || preRemove != null - || postRemove != null - || postLoad != null ) { - return new JpaEventListener( - JpaEventListenerStyle.CALLBACK, - managedTypeDetails, - prePersist, - postPersist, - preRemove, - postRemove, - preUpdate, - postUpdate, - postLoad - ); - } - return null; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/MappedSuperclassTypeMetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/MappedSuperclassTypeMetadataImpl.java deleted file mode 100644 index 79bec1261c..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/MappedSuperclassTypeMetadataImpl.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.List; - -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.boot.models.categorize.spi.MappedSuperclassTypeMetadata; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.models.spi.ClassDetails; - -import jakarta.persistence.AccessType; - -/** - * @author Steve Ebersole - */ -public class MappedSuperclassTypeMetadataImpl - extends AbstractIdentifiableTypeMetadata - implements MappedSuperclassTypeMetadata { - - private final List attributeList; - private final List hierarchyEventListeners; - private final List completeEventListeners; - - /** - * Form used when the mapped-superclass is the absolute-root of the hierarchy ("above" the root entity) - */ - public MappedSuperclassTypeMetadataImpl( - ClassDetails classDetails, - EntityHierarchy hierarchy, - MappedSuperclassTypeMetadataImpl superTypeMetadata, - AccessType defaultAccessType, - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext modelContext) { - super( classDetails, hierarchy, superTypeMetadata, defaultAccessType, modelContext ); - - final LifecycleCallbackCollector lifecycleCallbackCollector = new LifecycleCallbackCollector( classDetails, modelContext ); - this.attributeList = resolveAttributes( lifecycleCallbackCollector ); - this.hierarchyEventListeners = collectHierarchyEventListeners( lifecycleCallbackCollector.resolve() ); - this.completeEventListeners = collectCompleteEventListeners( modelContext ); - - if ( superTypeMetadata != null ) { - superTypeMetadata.addSubclass( this ); - } - - postInstantiate( false, typeConsumer ); - } - - - - /** - * Form used when the mapped-superclass is NOT the absolute-root of the hierarchy - */ - public MappedSuperclassTypeMetadataImpl( - ClassDetails classDetails, - EntityHierarchy hierarchy, - AbstractIdentifiableTypeMetadata superType, - HierarchyTypeConsumer typeConsumer, - ModelCategorizationContext modelContext) { - super( classDetails, hierarchy, superType, modelContext ); - - final LifecycleCallbackCollector lifecycleCallbackCollector = new LifecycleCallbackCollector( classDetails, modelContext ); - this.attributeList = resolveAttributes( lifecycleCallbackCollector ); - this.hierarchyEventListeners = collectHierarchyEventListeners( lifecycleCallbackCollector.resolve() ); - this.completeEventListeners = collectCompleteEventListeners( modelContext ); - - postInstantiate( true, typeConsumer ); - } - - @Override - protected List attributeList() { - return attributeList; - } - - @Override - public List getHierarchyJpaEventListeners() { - return hierarchyEventListeners; - } - - @Override - public List getCompleteJpaEventListeners() { - return completeEventListeners; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ModelCategorizationContextImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ModelCategorizationContextImpl.java deleted file mode 100644 index deccb863bf..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ModelCategorizationContextImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.List; - -import org.hibernate.boot.models.spi.GlobalRegistrations; -import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.boot.models.categorize.spi.ModelCategorizationContext; -import org.hibernate.models.spi.AnnotationDescriptorRegistry; -import org.hibernate.models.spi.ClassDetailsRegistry; - -import jakarta.persistence.SharedCacheMode; - -/** - * @author Steve Ebersole - */ -public class ModelCategorizationContextImpl implements ModelCategorizationContext { - private final ClassDetailsRegistry classDetailsRegistry; - private final AnnotationDescriptorRegistry annotationDescriptorRegistry; - private final GlobalRegistrations globalRegistrations; - private final SharedCacheMode sharedCacheMode; - - public ModelCategorizationContextImpl( - ClassDetailsRegistry classDetailsRegistry, - AnnotationDescriptorRegistry annotationDescriptorRegistry, - GlobalRegistrations globalRegistrations) { - this( classDetailsRegistry, annotationDescriptorRegistry, globalRegistrations, SharedCacheMode.UNSPECIFIED ); - } - - public ModelCategorizationContextImpl( - ClassDetailsRegistry classDetailsRegistry, - AnnotationDescriptorRegistry annotationDescriptorRegistry, - GlobalRegistrations globalRegistrations, - SharedCacheMode sharedCacheMode) { - this.classDetailsRegistry = classDetailsRegistry; - this.annotationDescriptorRegistry = annotationDescriptorRegistry; - this.globalRegistrations = globalRegistrations; - this.sharedCacheMode = sharedCacheMode; - } - - @Override - public ClassDetailsRegistry getClassDetailsRegistry() { - return classDetailsRegistry; - } - - @Override - public AnnotationDescriptorRegistry getAnnotationDescriptorRegistry() { - return annotationDescriptorRegistry; - } - - public GlobalRegistrations getGlobalRegistrations() { - return globalRegistrations; - } - - @Override - public SharedCacheMode getSharedCacheMode() { - return sharedCacheMode; - } - - @Override - public List getDefaultEventListeners() { - return getGlobalRegistrations().getEntityListenerRegistrations(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/NonAggregatedKeyMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/NonAggregatedKeyMappingImpl.java deleted file mode 100644 index 92178824d7..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/NonAggregatedKeyMappingImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.List; - -import org.hibernate.boot.models.categorize.spi.AttributeConsumer; -import org.hibernate.boot.models.categorize.spi.AttributeMetadata; -import org.hibernate.boot.models.categorize.spi.NonAggregatedKeyMapping; -import org.hibernate.models.spi.ClassDetails; - -/** - * @author Steve Ebersole - */ -public class NonAggregatedKeyMappingImpl implements NonAggregatedKeyMapping { - private final List idAttributes; - private final ClassDetails idClassType; - - public NonAggregatedKeyMappingImpl(List idAttributes, ClassDetails idClassType) { - this.idAttributes = idAttributes; - this.idClassType = idClassType; - } - - @Override - public List getIdAttributes() { - return idAttributes; - } - - @Override - public ClassDetails getIdClassType() { - return idClassType; - } - - @Override - public ClassDetails getKeyType() { - return idClassType; - } - - @Override - public void forEachAttribute(AttributeConsumer consumer) { - for ( int i = 0; i < idAttributes.size(); i++ ) { - consumer.accept( i, idAttributes.get( i ) ); - } - } - - @Override - public boolean contains(AttributeMetadata attributeMetadata) { - for ( int i = 0; i < idAttributes.size(); i++ ) { - if ( idAttributes.get( i ) == attributeMetadata ) { - return true; - } - } - return false; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/StandardPersistentAttributeMemberResolver.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/StandardPersistentAttributeMemberResolver.java deleted file mode 100644 index 216216edc8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/StandardPersistentAttributeMemberResolver.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.internal; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.function.BiConsumer; -import java.util.function.Function; - -import org.hibernate.annotations.Any; -import org.hibernate.annotations.AnyDiscriminator; -import org.hibernate.annotations.AnyDiscriminatorValue; -import org.hibernate.annotations.AnyDiscriminatorValues; -import org.hibernate.annotations.AnyKeyJavaClass; -import org.hibernate.annotations.AnyKeyJavaType; -import org.hibernate.annotations.AnyKeyJdbcType; -import org.hibernate.annotations.AnyKeyJdbcTypeCode; -import org.hibernate.annotations.JavaType; -import org.hibernate.annotations.JdbcType; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.annotations.ManyToAny; -import org.hibernate.annotations.Nationalized; -import org.hibernate.annotations.TenantId; -import org.hibernate.annotations.TimeZoneColumn; -import org.hibernate.annotations.TimeZoneStorage; -import org.hibernate.annotations.Type; -import org.hibernate.boot.internal.AnyKeyType; -import org.hibernate.boot.models.AccessTypePlacementException; -import org.hibernate.boot.models.AnnotationPlacementException; -import org.hibernate.boot.models.categorize.spi.ClassAttributeAccessType; -import org.hibernate.models.spi.AnnotationTarget; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.FieldDetails; -import org.hibernate.models.spi.MemberDetails; -import org.hibernate.models.spi.MethodDetails; - -import jakarta.annotation.Generated; -import jakarta.persistence.Access; -import jakarta.persistence.AccessType; -import jakarta.persistence.Basic; -import jakarta.persistence.Column; -import jakarta.persistence.ElementCollection; -import jakarta.persistence.Embedded; -import jakarta.persistence.EmbeddedId; -import jakarta.persistence.Enumerated; -import jakarta.persistence.Id; -import jakarta.persistence.Lob; -import jakarta.persistence.ManyToMany; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Temporal; -import jakarta.persistence.Version; - -/** - * Standard implementation of the PersistentAttributeMemberResolver contract - * based strictly on the JPA specification. - * - * @author Steve Ebersole - */ -public class StandardPersistentAttributeMemberResolver extends AbstractPersistentAttributeMemberResolver { - /** - * Singleton access - */ - public static final StandardPersistentAttributeMemberResolver INSTANCE = new StandardPersistentAttributeMemberResolver(); - - @Override - protected List resolveAttributesMembers( - Function transientFieldChecker, - Function transientMethodChecker, - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType) { - final LinkedHashMap results = new LinkedHashMap<>(); - - processAttributeLevelAccess( - results::put, - transientFieldChecker, - transientMethodChecker, - classDetails, - classLevelAccessType - ); - - processClassLevelAccess( - results::containsKey, - results::put, - transientFieldChecker, - transientMethodChecker, - classDetails, - classLevelAccessType - ); - - return new ArrayList<>( results.values() ); - } - - private void processAttributeLevelAccess( - BiConsumer memberConsumer, - Function transientFieldChecker, - Function transientMethodChecker, - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType) { - final List fields = classDetails.getFields(); - for ( int i = 0; i < fields.size(); i++ ) { - final FieldDetails fieldDetails = fields.get( i ); - processAttributeLevelAccessMember( fieldDetails, memberConsumer, transientFieldChecker, classDetails, classLevelAccessType ); - } - - final List methods = classDetails.getMethods(); - for ( int i = 0; i < methods.size(); i++ ) { - final MethodDetails methodDetails = methods.get( i ); - processAttributeLevelAccessMember( methodDetails, memberConsumer, transientMethodChecker, classDetails, classLevelAccessType ); - } - } - - private void processAttributeLevelAccessMember( - M memberDetails, - BiConsumer memberConsumer, - Function transiencyChecker, - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType) { - if ( transiencyChecker.apply( memberDetails ) ) { - // the field is transient - return; - } - - final Access access = memberDetails.getDirectAnnotationUsage( Access.class ); - if ( access == null ) { - checkForMisplacedAnnotations( classDetails, memberDetails, classLevelAccessType ); - return; - } - - final AccessType attributeAccessType = access.value(); - validateAttributeLevelAccess( memberDetails, attributeAccessType, classDetails ); - - memberConsumer.accept( memberDetails.resolveAttributeName(), memberDetails ); - } - - private void checkForMisplacedAnnotations( - ClassDetails classDetails, - M memberDetails, - ClassAttributeAccessType classLevelAccessType) { - // We have a case where the member did not define `@Access`. - // - // In such a case the member would only be an attribute backer if the member - // kind matched the class access-type. If the member kind does *not* match - // the class access-type, validate that it does not declare any mapping annotations - - if ( classLevelAccessType == null ) { - // nothing to check - return; - } - - if ( !matchesAccessType( memberDetails, classLevelAccessType ) ) { - if ( containsMappingAnnotations( memberDetails ) ) { - if ( memberDetails.getKind() == AnnotationTarget.Kind.FIELD ) { - throw new AnnotationPlacementException( - String.format( - Locale.ROOT, - "Field `%s#%s` declared mapping annotations even though it is not a persistent attribute", - classDetails.getName(), - memberDetails.getName() - ) - ); - } - else { - assert memberDetails.getKind() == AnnotationTarget.Kind.METHOD; - throw new AnnotationPlacementException( - String.format( - Locale.ROOT, - "Method `%s#%s` declared mapping annotations even though it is not a persistent attribute", - classDetails.getName(), - memberDetails.getName() - ) - ); - } - } - } - } - - private boolean matchesAccessType( - M memberDetails, - ClassAttributeAccessType classLevelAccessType) { - assert classLevelAccessType != null; - if ( classLevelAccessType.getJpaAccessType() == AccessType.FIELD ) { - return memberDetails.getKind() == AnnotationTarget.Kind.FIELD; - } - else { - return memberDetails.getKind() == AnnotationTarget.Kind.METHOD - && ( (MethodDetails) memberDetails ).getMethodKind() == MethodDetails.MethodKind.GETTER; - } - } - - private boolean containsMappingAnnotations(M memberDetails) { - // todo (jpa32) : better way to do this? - return memberDetails.hasDirectAnnotationUsage( Id.class ) - || memberDetails.hasDirectAnnotationUsage( EmbeddedId.class ) - || memberDetails.hasDirectAnnotationUsage( Version.class ) - || memberDetails.hasDirectAnnotationUsage( Basic.class ) - || memberDetails.hasDirectAnnotationUsage( Embedded.class ) - || memberDetails.hasDirectAnnotationUsage( ManyToOne.class ) - || memberDetails.hasDirectAnnotationUsage( OneToOne.class ) - || memberDetails.hasDirectAnnotationUsage( ElementCollection.class ) - || memberDetails.hasDirectAnnotationUsage( ManyToMany.class ) - || memberDetails.hasDirectAnnotationUsage( OneToMany.class ) - || memberDetails.hasDirectAnnotationUsage( Any.class ) - || memberDetails.hasDirectAnnotationUsage( ManyToAny.class ) - || memberDetails.hasDirectAnnotationUsage( AnyKeyJavaClass.class ) - || memberDetails.hasDirectAnnotationUsage( AnyKeyJavaType.class ) - || memberDetails.hasDirectAnnotationUsage( AnyKeyJdbcType.class ) - || memberDetails.hasDirectAnnotationUsage( AnyKeyJdbcTypeCode.class ) - || memberDetails.hasDirectAnnotationUsage( AnyKeyType.class ) - || memberDetails.hasDirectAnnotationUsage( AnyDiscriminator.class ) - || memberDetails.hasDirectAnnotationUsage( AnyDiscriminatorValue.class ) - || memberDetails.hasDirectAnnotationUsage( AnyDiscriminatorValues.class ) - || memberDetails.hasDirectAnnotationUsage( Column.class ) - || memberDetails.hasDirectAnnotationUsage( Enumerated.class ) - || memberDetails.hasDirectAnnotationUsage( Lob.class ) - || memberDetails.hasDirectAnnotationUsage( Temporal.class ) - || memberDetails.hasDirectAnnotationUsage( Nationalized.class ) - || memberDetails.hasDirectAnnotationUsage( TenantId.class ) - || memberDetails.hasDirectAnnotationUsage( Generated.class ) - || memberDetails.hasDirectAnnotationUsage( TimeZoneColumn.class ) - || memberDetails.hasDirectAnnotationUsage( TimeZoneStorage.class ) - || memberDetails.hasDirectAnnotationUsage( Type.class ) - || memberDetails.hasDirectAnnotationUsage( JavaType.class ) - || memberDetails.hasDirectAnnotationUsage( JdbcType.class ) - || memberDetails.hasDirectAnnotationUsage( JdbcTypeCode.class ); - } - - private void validateAttributeLevelAccess( - MemberDetails annotationTarget, - AccessType attributeAccessType, - ClassDetails classDetails) { - // Apply the checks defined in section `2.3.2 Explicit Access Type` of the persistence specification - - // Mainly, it is never legal to: - // 1. specify @Access(FIELD) on a getter - // 2. specify @Access(PROPERTY) on a field - - // todo (jpa32) : pass along access to JpaCompliance and use a new `JpaCompliance#isAnnotationPlacementComplianceEnabled` method here - // - for now, just allow it as we interpret the actual attribute AccessType value to dictate the state access - if ( !isAnnotationPlacementComplianceEnabled() ) { - return; - } - - if ( ( attributeAccessType == AccessType.FIELD && !annotationTarget.isField() ) - || ( attributeAccessType == AccessType.PROPERTY && annotationTarget.isField() ) ) { - throw new AccessTypePlacementException( classDetails, annotationTarget ); - } - } - - private boolean isAnnotationPlacementComplianceEnabled() { - return false; - } - - private void processClassLevelAccess( - Function alreadyProcessedChecker, - BiConsumer memberConsumer, - Function transientFieldChecker, - Function transientMethodChecker, - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType) { - if ( classLevelAccessType == null ) { - return; - } - - if ( classLevelAccessType.getJpaAccessType() == AccessType.FIELD ) { - final List fields = classDetails.getFields(); - for ( int i = 0; i < fields.size(); i++ ) { - final FieldDetails fieldDetails = fields.get( i ); - if ( !fieldDetails.isPersistable() ) { - // the field cannot be a persistent attribute - continue; - } - - final String attributeName = fieldDetails.resolveAttributeName(); - if ( alreadyProcessedChecker.apply( attributeName ) ) { - continue; - } - - if ( transientFieldChecker.apply( fieldDetails ) ) { - // the field is @Transient - continue; - } - - memberConsumer.accept( attributeName, fieldDetails ); - } - } - else { - assert classLevelAccessType.getJpaAccessType() == AccessType.PROPERTY; - final List methods = classDetails.getMethods(); - for ( int i = 0; i < methods.size(); i++ ) { - final MethodDetails methodDetails = methods.get( i ); - if ( !methodDetails.isPersistable() ) { - continue; - } - - final String attributeName = methodDetails.resolveAttributeName(); - if ( alreadyProcessedChecker.apply( attributeName ) ) { - continue; - } - - if ( transientMethodChecker.apply( methodDetails ) ) { - // the method is @Transient - continue; - } - - memberConsumer.accept( attributeName, methodDetails ); - } - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/package-info.java deleted file mode 100644 index a1c8953544..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. - */ - -/** - * Support for processing an application's domain model, as known through - * {@linkplain org.hibernate.boot.model.process.spi.ManagedResources} and ultimately - * producing a mildly {@linkplain org.hibernate.boot.models.categorize.spi.CategorizedDomainModel categorized model} - * representing entities, embeddables, etc. - *

- * Happens in 2 steps -

    - *
  1. - * Create the "source metamodel" - {@linkplain org.hibernate.models.spi.ClassDetails classes}, - * {@linkplain org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl XML}, etc. - *
  2. - *
  3. - * Process this "source metamodel" and produce the {@linkplain org.hibernate.boot.models.categorize.spi.CategorizedDomainModel categorized model} - *
  4. - *
- * - * @author Steve Ebersole - */ -package org.hibernate.boot.models.categorize; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AggregatedKeyMapping.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AggregatedKeyMapping.java deleted file mode 100644 index 01f26ac3c3..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AggregatedKeyMapping.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -/** - * CompositeIdMapping which is physically an embeddable and represented by a single attribute. - * - * @see jakarta.persistence.EmbeddedId - * - * @author Steve Ebersole - */ -public interface AggregatedKeyMapping extends CompositeKeyMapping, SingleAttributeKeyMapping { -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AllMemberConsumer.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AllMemberConsumer.java deleted file mode 100644 index ed15940982..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AllMemberConsumer.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.models.spi.MemberDetails; - -/** - * @author Steve Ebersole - */ -@FunctionalInterface -public interface AllMemberConsumer { - void acceptMember(MemberDetails memberDetails); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeConsumer.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeConsumer.java deleted file mode 100644 index c1564e2247..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeConsumer.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.internal.util.IndexedConsumer; - -/** - * @author Steve Ebersole - */ -@FunctionalInterface -public interface AttributeConsumer extends IndexedConsumer { - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeMetadata.java deleted file mode 100644 index 61ad768078..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/AttributeMetadata.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - - -import org.hibernate.models.spi.MemberDetails; - -/** - * Metadata about a persistent attribute - * - * @author Steve Ebersole - */ -public interface AttributeMetadata extends TableOwner { - /** - * The attribute name - */ - String getName(); - - /** - * The persistent nature of the attribute - */ - AttributeNature getNature(); - - /** - * The backing member - */ - MemberDetails getMember(); - - /** - * An enum defining the nature (categorization) of a persistent attribute. - * - * @see jakarta.persistence.metamodel.Attribute.PersistentAttributeType - */ - enum AttributeNature { - BASIC, - EMBEDDED, - ANY, - TO_ONE, - ELEMENT_COLLECTION, - MANY_TO_ANY, - MANY_TO_MANY, - ONE_TO_MANY - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/BasicKeyMapping.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/BasicKeyMapping.java deleted file mode 100644 index 8ac13393b0..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/BasicKeyMapping.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -/** - * @author Steve Ebersole - */ -public interface BasicKeyMapping extends SingleAttributeKeyMapping { -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CacheRegion.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CacheRegion.java deleted file mode 100644 index 50d7ec3d9b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CacheRegion.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; -import org.hibernate.boot.CacheRegionDefinition; -import org.hibernate.cache.spi.access.AccessType; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.models.ModelsException; - -/** - * Models the caching options for an entity, natural-id, or collection. - * - * @author Steve Ebersole - * @author Hardy Ferentschik - */ -public class CacheRegion { - private String regionName; - private AccessType accessType; - private boolean cacheLazyProperties; - - public CacheRegion( - Cache cacheAnnotation, - AccessType implicitCacheAccessType, - String implicitRegionName) { - if ( cacheAnnotation == null ) { - regionName = implicitRegionName; - accessType = implicitCacheAccessType; - cacheLazyProperties = true; - } - else { - final String explicitRegionName = cacheAnnotation.region(); - regionName = StringHelper.isEmpty( explicitRegionName ) ? implicitRegionName : explicitRegionName; - - accessType = interpretAccessStrategy( cacheAnnotation.usage() ); - - // default for includeLazy is true - // default for include is "all" - final boolean includeLazy = cacheAnnotation.includeLazy(); - final String include = cacheAnnotation.include(); - assert "all".equals( include ) || "non-lazy".equals( include ); - cacheLazyProperties = includeLazy && include.equals( "all" ) ; - } - } - - private AccessType interpretAccessStrategy(CacheConcurrencyStrategy usage) { - if ( usage == null ) { - return null; - } - switch ( usage ) { - case NONE: { - return null; - } - case READ_ONLY: { - return AccessType.READ_ONLY; - } - case READ_WRITE: { - return AccessType.READ_WRITE; - } - case NONSTRICT_READ_WRITE: { - return AccessType.NONSTRICT_READ_WRITE; - } - case TRANSACTIONAL: { - return AccessType.TRANSACTIONAL; - } - default: { - throw new ModelsException( "Unexpected cache concurrency strategy specified - " + usage ); - } - } - } - - public String getRegionName() { - return regionName; - } - - public void setRegionName(String regionName) { - this.regionName = regionName; - } - - public AccessType getAccessType() { - return accessType; - } - - public void setAccessType(AccessType accessType) { - this.accessType = accessType; - } - - public boolean isCacheLazyProperties() { - return cacheLazyProperties; - } - - public void setCacheLazyProperties(boolean cacheLazyProperties) { - this.cacheLazyProperties = cacheLazyProperties; - } - - public void overlay(CacheRegionDefinition overrides) { - if ( overrides == null ) { - return; - } - - accessType = AccessType.fromExternalName( overrides.getUsage() ); - if ( StringHelper.isEmpty( overrides.getRegion() ) ) { - regionName = overrides.getRegion(); - } - // ugh, primitive boolean - cacheLazyProperties = overrides.isCacheLazy(); - } - - public void overlay(CacheRegion overrides) { - if ( overrides == null ) { - return; - } - - this.accessType = overrides.accessType; - this.regionName = overrides.regionName; - this.cacheLazyProperties = overrides.cacheLazyProperties; - } - - @Override - public String toString() { - return "Caching{" + - "region='" + regionName + '\'' - + ", accessType=" + accessType - + ", cacheLazyProperties=" + cacheLazyProperties + '}'; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CategorizedDomainModel.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CategorizedDomainModel.java deleted file mode 100644 index 626e889310..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CategorizedDomainModel.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.Map; -import java.util.Set; - -import org.hibernate.boot.models.spi.GlobalRegistrations; -import org.hibernate.boot.models.xml.spi.PersistenceUnitMetadata; -import org.hibernate.internal.util.IndexedConsumer; -import org.hibernate.internal.util.KeyedConsumer; -import org.hibernate.models.spi.AnnotationDescriptorRegistry; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; - -/** - * The application's domain model, understood at a very rudimentary level - we know - * a class is an entity, a mapped-superclass, ... And we know about persistent attributes, - * but again on a very rudimentary level. - *

- * We also know about all {@linkplain #getGlobalRegistrations() global registrations} - - * sequence-generators, named-queries, ... - * - * @author Steve Ebersole - */ -public interface CategorizedDomainModel { - /** - * Registry of all known classes - */ - ClassDetailsRegistry getClassDetailsRegistry(); - - /** - * Registry of all known {@linkplain java.lang.annotation.Annotation} descriptors (classes) - */ - AnnotationDescriptorRegistry getAnnotationDescriptorRegistry(); - - PersistenceUnitMetadata getPersistenceUnitMetadata(); - - /** - * Global registrations collected while processing the persistence-unit. - */ - GlobalRegistrations getGlobalRegistrations(); - - /** - * All entity hierarchies defined in the persistence unit - */ - Set getEntityHierarchies(); - - /** - * Iteration over the {@linkplain #getEntityHierarchies() entity hierarchies} - */ - default void forEachEntityHierarchy(IndexedConsumer hierarchyConsumer) { - final Set entityHierarchies = getEntityHierarchies(); - if ( entityHierarchies.isEmpty() ) { - return; - } - - int pos = 0; - for ( EntityHierarchy entityHierarchy : entityHierarchies ) { - hierarchyConsumer.accept( pos, entityHierarchy ); - pos++; - } - } - - /** - * All mapped-superclasses defined in the persistence unit - */ - Map getMappedSuperclasses(); - - /** - * Iteration over the {@linkplain #getMappedSuperclasses() mapped superclasses} - */ - default void forEachMappedSuperclass(KeyedConsumer consumer) { - final Map mappedSuperclasses = getMappedSuperclasses(); - if ( mappedSuperclasses.isEmpty() ) { - return; - } - - mappedSuperclasses.forEach( consumer::accept ); - } - - /** - * All embeddables defined in the persistence unit - */ - Map getEmbeddables(); - - /** - * Iteration over the {@linkplain #getEmbeddables() embeddables} - */ - - default void forEachEmbeddable(KeyedConsumer consumer) { - final Map embeddables = getEmbeddables(); - if ( embeddables.isEmpty() ) { - return; - } - - embeddables.forEach( consumer::accept ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ClassAttributeAccessType.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ClassAttributeAccessType.java deleted file mode 100644 index b41a6b5712..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ClassAttributeAccessType.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import jakarta.persistence.AccessType; - -/** - * Possible class-level {@linkplain jakarta.persistence.AccessType} values. - * - * @author Steve Ebersole - */ -public enum ClassAttributeAccessType { - /** - * The class explicitly defined field access via {@linkplain jakarta.persistence.Access} - */ - EXPLICIT_FIELD(true, AccessType.FIELD), - - /** - * The class explicitly defined property access via {@linkplain jakarta.persistence.Access} - */ - EXPLICIT_PROPERTY(true, AccessType.PROPERTY), - - /** - * The class implicitly defined field access. - */ - IMPLICIT_FIELD(false, AccessType.FIELD), - - /** - * The class implicitly defined property access. - */ - IMPLICIT_PROPERTY(false, AccessType.PROPERTY); - - private final boolean explicit; - private final AccessType jpaAccessType; - - ClassAttributeAccessType(boolean explicit, AccessType jpaAccessType) { - this.explicit = explicit; - this.jpaAccessType = jpaAccessType; - } - - /** - * Whether the access-type was explicitly specified - */ - public boolean isExplicit() { - return explicit; - } - - /** - * The corresponding {@linkplain jakarta.persistence.AccessType} - */ - public AccessType getJpaAccessType() { - return jpaAccessType; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CompositeKeyMapping.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CompositeKeyMapping.java deleted file mode 100644 index 367360c623..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/CompositeKeyMapping.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -/** - * Id-mapping which is embeddable - either {@linkplain AggregatedKeyMapping physically} - * or {@linkplain NonAggregatedKeyMapping virtually}. - * - * @author Steve Ebersole - */ -public interface CompositeKeyMapping extends KeyMapping { -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityHierarchy.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityHierarchy.java deleted file mode 100644 index b2356793b9..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityHierarchy.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.engine.OptimisticLockStyle; - -import jakarta.persistence.AccessType; -import jakarta.persistence.InheritanceType; - -/** - * Models an entity hierarchy comprised of {@linkplain EntityTypeMetadata entity} - * and {@linkplain MappedSuperclassTypeMetadata mapped-superclass} types. - * - * @author Steve Ebersole - */ -public interface EntityHierarchy { - /** - * The hierarchy's root type. - */ - EntityTypeMetadata getRoot(); - - /** - * The absolute root of the hierarchy, which might be a mapped-superclass - * above the {@linkplain #getRoot() root entity} - */ - IdentifiableTypeMetadata getAbsoluteRoot(); - - /** - * Visit each type in the hierarchy, top down starting from {@linkplain #getAbsoluteRoot()} - */ - void forEachType(HierarchyTypeVisitor typeVisitor); - - /** - * The default access-type for the hierarchy. See section 2.3.1 Default Access Type - * of the Jakarta Persistence specification. - */ - AccessType getDefaultAccessType(); - - /** - * The inheritance strategy for the hierarchy. - */ - InheritanceType getInheritanceType(); - - KeyMapping getIdMapping(); - - KeyMapping getNaturalIdMapping(); - - AttributeMetadata getVersionAttribute(); - - AttributeMetadata getTenantIdAttribute(); - - /** - * Style of optimistic locking for the hierarchy. - */ - OptimisticLockStyle getOptimisticLockStyle(); - - /** - * The caching configuration for entities in this hierarchy. - */ - CacheRegion getCacheRegion(); - - /** - * The caching configuration for this hierarchy's {@linkplain org.hibernate.annotations.NaturalId natural-id} - */ - NaturalIdCacheRegion getNaturalIdCacheRegion(); - - /** - * Describes a type's place in the hierarchy relative to the {@linkplain #getRoot() root entity} - */ - enum HierarchyRelation { SUPER, ROOT, SUB } - - @FunctionalInterface - interface HierarchyTypeVisitor { - void visitType( - IdentifiableTypeMetadata type, - IdentifiableTypeMetadata superType, - EntityHierarchy hierarchy, - HierarchyRelation relation); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityTypeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityTypeMetadata.java deleted file mode 100644 index e64b95c984..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/EntityTypeMetadata.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.Map; - -import org.hibernate.boot.model.CustomSql; -import org.hibernate.boot.model.naming.EntityNaming; - -/** - * Metadata about an {@linkplain jakarta.persistence.metamodel.EntityType entity type} - * - * @author Steve Ebersole - */ -public interface EntityTypeMetadata extends IdentifiableTypeMetadata, EntityNaming { - @Override - default Kind getManagedTypeKind() { - return Kind.ENTITY; - } - - /** - * The Hibernate notion of entity-name, used for dynamic models - */ - String getEntityName(); - - /** - * The JPA notion of entity-name, used for HQL references (import) - */ - String getJpaEntityName(); - - /** - * Whether the state of the entity is written to the database (mutable) or not (immutable) - */ - boolean isMutable(); - - /** - * Whether this entity is cacheable. - * - * @see jakarta.persistence.Cacheable - * @see org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor#getSharedCacheMode() - */ - boolean isCacheable(); - - /** - * Any tables to which this entity maps that Hibernate does not know about. - * - * @see org.hibernate.annotations.View - * @see org.hibernate.annotations.Subselect - */ - String[] getSynchronizedTableNames(); - - /** - * A size to use for the entity with batch loading - */ - int getBatchSize(); - - /** - * Whether to perform dynamic inserts. - * - * @see org.hibernate.annotations.DynamicInsert - */ - boolean isDynamicInsert(); - - /** - * Whether to perform dynamic updates. - * - * @see org.hibernate.annotations.DynamicUpdate - */ - boolean isDynamicUpdate(); - - /** - * Custom SQL to perform an INSERT of this entity - */ - Map getCustomInserts(); - - /** - * Custom SQL to perform an UPDATE of this entity - */ - Map getCustomUpdates(); - - /** - * Custom SQL to perform an DELETE of this entity - */ - Map getCustomDeletes(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/IdentifiableTypeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/IdentifiableTypeMetadata.java deleted file mode 100644 index e40decfdf5..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/IdentifiableTypeMetadata.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.List; -import java.util.function.Consumer; - -import org.hibernate.boot.models.spi.JpaEventListener; - -/** - * Metadata about an {@linkplain jakarta.persistence.metamodel.IdentifiableType identifiable type} - * - * @author Steve Ebersole - */ -public interface IdentifiableTypeMetadata extends ManagedTypeMetadata, TableOwner { - /** - * The hierarchy in which this IdentifiableType occurs. - */ - EntityHierarchy getHierarchy(); - - /** - * The super-type, if one - */ - - IdentifiableTypeMetadata getSuperType(); - - /** - * Whether this type is considered abstract. - */ - default boolean isAbstract() { - return getClassDetails().isAbstract(); - } - - /** - * Whether this type has subtypes - */ - boolean hasSubTypes(); - - /** - * Get the number of direct subtypes - */ - int getNumberOfSubTypes(); - - /** - * Get the direct subtypes - */ - Iterable getSubTypes(); - - /** - * Visit each direct subtype - */ - void forEachSubType(Consumer consumer); - - /** - * Event listeners in effect for this type, minus - * {@linkplain jakarta.persistence.ExcludeDefaultListeners default listeners}. - * - * @apiNote Kept separate from {@linkplain #getCompleteJpaEventListeners()} - * to facilitate types building their complete set with their - * {@linkplain jakarta.persistence.ExcludeSuperclassListeners superclass listeners}. - */ - List getHierarchyJpaEventListeners(); - - /** - * Event listeners in effect for this type, including - * {@linkplain jakarta.persistence.ExcludeDefaultListeners default listeners} - */ - List getCompleteJpaEventListeners(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/KeyMapping.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/KeyMapping.java deleted file mode 100644 index dddd9b7963..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/KeyMapping.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.models.spi.ClassDetails; - -/** - * @author Steve Ebersole - */ -public interface KeyMapping { - ClassDetails getKeyType(); - - void forEachAttribute(AttributeConsumer consumer); - - boolean contains(AttributeMetadata attributeMetadata); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedResourcesProcessor.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedResourcesProcessor.java deleted file mode 100644 index b00d07e1cd..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedResourcesProcessor.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.hibernate.Internal; -import org.hibernate.boot.internal.MetadataBuilderImpl; -import org.hibernate.boot.internal.RootMappingDefaults; -import org.hibernate.boot.model.process.spi.ManagedResources; -import org.hibernate.boot.models.categorize.ModelCategorizationLogging; -import org.hibernate.boot.models.categorize.internal.ClassLoaderServiceLoading; -import org.hibernate.boot.models.internal.DomainModelCategorizationCollector; -import org.hibernate.boot.models.internal.GlobalRegistrationsImpl; -import org.hibernate.boot.models.categorize.internal.ModelCategorizationContextImpl; -import org.hibernate.boot.models.internal.ModelsHelper; -import org.hibernate.boot.models.xml.internal.PersistenceUnitMetadataImpl; -import org.hibernate.boot.models.xml.spi.XmlPreProcessingResult; -import org.hibernate.boot.models.xml.spi.XmlPreProcessor; -import org.hibernate.boot.models.xml.spi.XmlProcessingResult; -import org.hibernate.boot.models.xml.spi.XmlProcessor; -import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; -import org.hibernate.boot.spi.BootstrapContext; -import org.hibernate.boot.spi.MetadataBuildingOptions; -import org.hibernate.models.internal.BasicModelBuildingContextImpl; -import org.hibernate.models.spi.AnnotationDescriptorRegistry; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; - -import static org.hibernate.boot.models.categorize.internal.EntityHierarchyBuilder.createEntityHierarchies; -import static org.hibernate.internal.util.collections.CollectionHelper.mutableJoin; - -/** - * Processes a {@linkplain ManagedResources} (classes, mapping, etc.) and - * produces a {@linkplain CategorizedDomainModel categorized domain model} - * - * @author Steve Ebersole - */ -public class ManagedResourcesProcessor { - public static CategorizedDomainModel processManagedResources( - ManagedResources managedResources, - MetadataBuildingOptions metadataBuildingOptions, - BootstrapContext bootstrapContext) { - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // - pre-process the XML - // - collect all known classes - // - resolve (possibly building) Jandex index - // - build the SourceModelBuildingContext - // - // INPUTS: - // - serviceRegistry - // - managedResources - // - bootstrapContext (supplied Jandex index, if one) - // - // OUTPUTS: - // - xmlPreProcessingResult - // - allKnownClassNames (technically could be included in xmlPreProcessingResult) - // - sourceModelBuildingContext - - final ClassLoaderService classLoaderService = bootstrapContext.getServiceRegistry().getService( ClassLoaderService.class ); - final ClassLoaderServiceLoading classLoading = new ClassLoaderServiceLoading( classLoaderService ); - - final PersistenceUnitMetadataImpl persistenceUnitMetadata = new PersistenceUnitMetadataImpl(); - - final XmlPreProcessingResult xmlPreProcessingResult = XmlPreProcessor.preProcessXmlResources( - managedResources, - persistenceUnitMetadata - ); - - //noinspection unchecked - final List allKnownClassNames = mutableJoin( - managedResources.getAnnotatedClassReferences().stream().map( Class::getName ).collect( Collectors.toList() ), - managedResources.getAnnotatedClassNames(), - xmlPreProcessingResult.getMappedClasses() - ); - managedResources.getAnnotatedPackageNames().forEach( (packageName) -> { - try { - final Class packageInfoClass = classLoading.classForName( packageName + ".package-info" ); - allKnownClassNames.add( packageInfoClass.getName() ); - } - catch (ClassLoadingException classLoadingException) { - // no package-info, so there can be no annotations... just skip it - } - } ); - managedResources.getAnnotatedClassReferences().forEach( (clazz) -> allKnownClassNames.add( clazz.getName() ) ); - - // At this point we know all managed class names across all sources. - // Resolve the Jandex Index and build the SourceModelBuildingContext. - final BasicModelBuildingContextImpl sourceModelBuildingContext = new BasicModelBuildingContextImpl( - classLoading, - ModelsHelper::preFillRegistries - ); - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // - process metadata-complete XML - // - collect overlay XML - // - process annotations (including those from metadata-complete XML) - // - apply overlay XML - // - // INPUTS: - // - "options" (areIdGeneratorsGlobal, etc) - // - xmlPreProcessingResult - // - sourceModelBuildingContext - // - // OUTPUTS - // - rootEntities - // - mappedSuperClasses - // - embeddables - - // JPA id generator global-ity thing - final boolean areIdGeneratorsGlobal = true; - final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry(); - final AnnotationDescriptorRegistry descriptorRegistry = sourceModelBuildingContext.getAnnotationDescriptorRegistry(); - final GlobalRegistrationsImpl globalRegistrations = new GlobalRegistrationsImpl( sourceModelBuildingContext, bootstrapContext ); - final DomainModelCategorizationCollector modelCategorizationCollector = new DomainModelCategorizationCollector( - areIdGeneratorsGlobal, - globalRegistrations, - sourceModelBuildingContext - ); - - final RootMappingDefaults rootMappingDefaults = new RootMappingDefaults( - metadataBuildingOptions.getMappingDefaults(), - persistenceUnitMetadata - ); - final XmlProcessingResult xmlProcessingResult = XmlProcessor.processXml( - xmlPreProcessingResult, - modelCategorizationCollector, - sourceModelBuildingContext, - bootstrapContext, - rootMappingDefaults - ); - - allKnownClassNames.forEach( (className) -> { - final ClassDetails classDetails = classDetailsRegistry.resolveClassDetails( className ); - modelCategorizationCollector.apply( classDetails ); - } ); - xmlPreProcessingResult.getMappedNames().forEach( (className) -> { - final ClassDetails classDetails = classDetailsRegistry.resolveClassDetails( className ); - modelCategorizationCollector.apply( classDetails ); - } ); - - xmlProcessingResult.apply( xmlPreProcessingResult.getPersistenceUnitMetadata() ); - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // - create entity-hierarchies - // - create the CategorizedDomainModel - // - // INPUTS: - // - rootEntities - // - mappedSuperClasses - // - embeddables - // - // OUTPUTS: - // - CategorizedDomainModel - - - // Collect the entity hierarchies based on the set of `rootEntities` - final ModelCategorizationContextImpl mappingBuildingContext = new ModelCategorizationContextImpl( - classDetailsRegistry, - descriptorRegistry, - globalRegistrations - ); - - final Set entityHierarchies; - if ( ModelCategorizationLogging.MODEL_CATEGORIZATION_LOGGER.isDebugEnabled() ) { - final Map unusedMappedSuperClasses = new HashMap<>( modelCategorizationCollector.getMappedSuperclasses() ); - entityHierarchies = createEntityHierarchies( - modelCategorizationCollector.getRootEntities(), - (identifiableType) -> { - if ( identifiableType instanceof MappedSuperclassTypeMetadata ) { - unusedMappedSuperClasses.remove( identifiableType.getClassDetails().getClassName() ); - } - }, - mappingBuildingContext - ); - warnAboutUnusedMappedSuperclasses( unusedMappedSuperClasses ); - } - else { - entityHierarchies = createEntityHierarchies( - modelCategorizationCollector.getRootEntities(), - ManagedResourcesProcessor::ignore, - mappingBuildingContext - ); - } - - return modelCategorizationCollector.createResult( - entityHierarchies, - xmlPreProcessingResult.getPersistenceUnitMetadata(), - classDetailsRegistry, - descriptorRegistry - ); - } - - private static void ignore(IdentifiableTypeMetadata identifiableTypeMetadata) { - } - - private static void warnAboutUnusedMappedSuperclasses(Map mappedSuperClasses) { - assert ModelCategorizationLogging.MODEL_CATEGORIZATION_LOGGER.isDebugEnabled(); - for ( Map.Entry entry : mappedSuperClasses.entrySet() ) { - ModelCategorizationLogging.MODEL_CATEGORIZATION_LOGGER.debugf( - "Encountered MappedSuperclass [%s] which was unused in any entity hierarchies", - entry.getKey() - ); - } - } - - /** - * For testing use only - */ - @Internal - public static CategorizedDomainModel processManagedResources( - ManagedResources managedResources, - BootstrapContext bootstrapContext) { - return processManagedResources( - managedResources, - new MetadataBuilderImpl.MetadataBuildingOptionsImpl( bootstrapContext.getServiceRegistry() ), - bootstrapContext - ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedTypeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedTypeMetadata.java deleted file mode 100644 index fd524a3551..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ManagedTypeMetadata.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.Collection; - -import org.hibernate.internal.util.IndexedConsumer; -import org.hibernate.models.spi.ClassDetails; - - -/** - * Metadata about a {@linkplain jakarta.persistence.metamodel.ManagedType managed type} - * - * @author Steve Ebersole - */ -public interface ManagedTypeMetadata { - - enum Kind { ENTITY, MAPPED_SUPER, EMBEDDABLE } - - Kind getManagedTypeKind(); - - /** - * The underlying managed-class - */ - ClassDetails getClassDetails(); - - /** - * The class-level access type - */ - ClassAttributeAccessType getClassLevelAccessType(); - - /** - * Get the number of declared attributes - */ - int getNumberOfAttributes(); - - /** - * Get the declared attributes - */ - Collection getAttributes(); - - AttributeMetadata findAttribute(String name); - - /** - * Visit each declared attributes - */ - void forEachAttribute(IndexedConsumer consumer); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/MappedSuperclassTypeMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/MappedSuperclassTypeMetadata.java deleted file mode 100644 index 608e2a0110..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/MappedSuperclassTypeMetadata.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -/** - * Metadata about a {@linkplain jakarta.persistence.metamodel.MappedSuperclassType mapped-superclass} - * - * @author Steve Ebersole - */ -public interface MappedSuperclassTypeMetadata extends IdentifiableTypeMetadata { - @Override - default Kind getManagedTypeKind() { - return Kind.MAPPED_SUPER; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ModelCategorizationContext.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ModelCategorizationContext.java deleted file mode 100644 index ce36a08251..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/ModelCategorizationContext.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.List; - -import org.hibernate.boot.models.categorize.internal.StandardPersistentAttributeMemberResolver; -import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.models.spi.AnnotationDescriptorRegistry; -import org.hibernate.models.spi.ClassDetailsRegistry; - -import jakarta.persistence.SharedCacheMode; - -/** - * Contextual information used while building {@linkplain ManagedTypeMetadata} and friends. - * - * @author Steve Ebersole - */ -public interface ModelCategorizationContext { - ClassDetailsRegistry getClassDetailsRegistry(); - - AnnotationDescriptorRegistry getAnnotationDescriptorRegistry(); - - SharedCacheMode getSharedCacheMode(); - - default PersistentAttributeMemberResolver getPersistentAttributeMemberResolver() { - return StandardPersistentAttributeMemberResolver.INSTANCE; - } - - List getDefaultEventListeners(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NaturalIdCacheRegion.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NaturalIdCacheRegion.java deleted file mode 100644 index 7ec2b91467..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NaturalIdCacheRegion.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.annotations.NaturalIdCache; -import org.hibernate.internal.util.StringHelper; - -/** - * Details about caching related to the natural-id of an entity - * - * @see CacheRegion - * - * @author Steve Ebersole - */ -public class NaturalIdCacheRegion { - private final String regionName; - - public NaturalIdCacheRegion(NaturalIdCache cacheAnnotation, CacheRegion cacheRegion) { - this.regionName = determineRegionName( cacheAnnotation, cacheRegion ); - } - - private static String determineRegionName(NaturalIdCache cacheAnnotation, CacheRegion cacheRegion) { - if ( cacheAnnotation != null ) { - final String explicitRegionName = cacheAnnotation.region(); - if ( StringHelper.isNotEmpty( explicitRegionName ) ) { - return explicitRegionName; - } - } - - // use the default value - return cacheRegion.getRegionName() + "##NaturalId"; - } - - public String getRegionName() { - return regionName; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NonAggregatedKeyMapping.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NonAggregatedKeyMapping.java deleted file mode 100644 index 3da758d80e..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/NonAggregatedKeyMapping.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.List; - -import org.hibernate.models.spi.ClassDetails; - -/** - * CompositeIdMapping which is virtually an embeddable and represented by one-or-more - * {@linkplain #getIdAttributes id-attributes} identified by one-or-more {@code @Id} - * annotations. - * Also defines an {@linkplain #getIdClassType() id-class} which is used for loading. - - * @see jakarta.persistence.Id - * @see jakarta.persistence.IdClass - * - * @author Steve Ebersole - */ -public interface NonAggregatedKeyMapping extends CompositeKeyMapping { - /** - * The attributes making up the composition. - */ - List getIdAttributes(); - - /** - * Details about the {@linkplain jakarta.persistence.IdClass id-class}. - * - * @see jakarta.persistence.IdClass - */ - ClassDetails getIdClassType(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/PersistentAttributeMemberResolver.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/PersistentAttributeMemberResolver.java deleted file mode 100644 index 6ad7213b6e..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/PersistentAttributeMemberResolver.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import java.util.List; - -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.MemberDetails; - - -/** - * Contract responsible for resolving the members that identify the persistent - * attributes for a given class descriptor representing a managed type. - *

- * These members (field or method) would be where we look for mapping annotations - * for the attribute. - *

- * Additionally, whether the member is a field or method would tell us the default - * runtime {@linkplain org.hibernate.property.access.spi.PropertyAccessStrategy access strategy} - * - * @author Steve Ebersole - */ -public interface PersistentAttributeMemberResolver { - /** - * Given the class descriptor representing a ManagedType and the implicit AccessType - * to use, resolve the members that indicate persistent attributes. - * - * @param classDetails Descriptor of the class - * @param classLevelAccessType The implicit AccessType - * @param allMemberConsumer Optional callback for each member on the class - * - * @return The list of "backing members" - */ - List resolveAttributesMembers( - ClassDetails classDetails, - ClassAttributeAccessType classLevelAccessType, - AllMemberConsumer allMemberConsumer); - -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/SingleAttributeKeyMapping.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/SingleAttributeKeyMapping.java deleted file mode 100644 index 2b8d7d12cc..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/SingleAttributeKeyMapping.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -import org.hibernate.models.spi.ClassDetails; - -/** - * @author Steve Ebersole - */ -public interface SingleAttributeKeyMapping extends KeyMapping { - AttributeMetadata getAttribute(); - - default String getAttributeName() { - return getAttribute().getName(); - } - - default ClassDetails getKeyType() { - return getAttribute().getMember().getType().determineRawClass(); - } - - @Override - default void forEachAttribute(AttributeConsumer consumer) { - consumer.accept( 0, getAttribute() ); - } - - @Override - default boolean contains(AttributeMetadata attributeMetadata) { - return attributeMetadata == getAttribute(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/TableOwner.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/TableOwner.java deleted file mode 100644 index f8f26ad72f..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/spi/TableOwner.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.boot.models.categorize.spi; - -/** - * Marker for things which can "own" a table - * - * @author Steve Ebersole - */ -public interface TableOwner { -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ClassLoaderServiceLoading.java b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/ClassLoaderServiceLoading.java similarity index 96% rename from hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ClassLoaderServiceLoading.java rename to hibernate-core/src/main/java/org/hibernate/boot/models/internal/ClassLoaderServiceLoading.java index ca3fbd07dc..a1eaebc759 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/ClassLoaderServiceLoading.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/ClassLoaderServiceLoading.java @@ -2,7 +2,7 @@ * SPDX-License-Identifier: LGPL-2.1-or-later * Copyright Red Hat Inc. and Hibernate Authors */ -package org.hibernate.boot.models.categorize.internal; +package org.hibernate.boot.models.internal; import java.net.URL; import java.util.Collection; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java index 1448018ae3..c24f37a262 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java @@ -4,38 +4,30 @@ */ package org.hibernate.boot.models.internal; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerContainerImpl; -import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; -import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl; -import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadataImpl; -import org.hibernate.boot.models.categorize.internal.CategorizedDomainModelImpl; -import org.hibernate.boot.models.categorize.spi.CategorizedDomainModel; -import org.hibernate.boot.models.categorize.spi.EntityHierarchy; -import org.hibernate.boot.models.spi.GlobalRegistrations; -import org.hibernate.boot.models.xml.spi.PersistenceUnitMetadata; -import org.hibernate.boot.models.xml.spi.XmlDocumentContext; -import org.hibernate.models.spi.AnnotationDescriptorRegistry; -import org.hibernate.models.spi.ClassDetails; -import org.hibernate.models.spi.ClassDetailsRegistry; -import org.hibernate.models.spi.SourceModelBuildingContext; - import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; import jakarta.persistence.Embeddable; import jakarta.persistence.Entity; import jakarta.persistence.MappedSuperclass; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerContainerImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadataImpl; +import org.hibernate.boot.models.spi.GlobalRegistrations; +import org.hibernate.boot.models.xml.spi.XmlDocumentContext; +import org.hibernate.models.spi.ClassDetails; +import org.hibernate.models.spi.SourceModelBuildingContext; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * In-flight holder for various things as we process metadata sources * * @author Steve Ebersole */ - public class DomainModelCategorizationCollector { private final boolean areIdGeneratorsGlobal; @@ -162,20 +154,4 @@ public class DomainModelCategorizationCollector { // if we hit no opt-outs we have a root return true; } - - public CategorizedDomainModel createResult( - Set entityHierarchies, - PersistenceUnitMetadata persistenceUnitMetadata, - ClassDetailsRegistry classDetailsRegistry, - AnnotationDescriptorRegistry annotationDescriptorRegistry) { - return new CategorizedDomainModelImpl( - classDetailsRegistry, - annotationDescriptorRegistry, - persistenceUnitMetadata, - entityHierarchies, - mappedSuperclasses, - embeddables, - getGlobalRegistrations() - ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java index 53bf4a15d6..c2c31aec40 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java @@ -61,7 +61,7 @@ import org.hibernate.boot.models.spi.GlobalRegistrations; import org.hibernate.boot.models.spi.JavaTypeRegistration; import org.hibernate.boot.models.spi.JdbcTypeRegistration; import org.hibernate.boot.models.spi.JpaEventListener; -import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle; +import org.hibernate.boot.models.JpaEventListenerStyle; import org.hibernate.boot.models.spi.NamedNativeQueryRegistration; import org.hibernate.boot.models.spi.NamedQueryRegistration; import org.hibernate.boot.models.spi.NamedStoredProcedureQueryRegistration; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/spi/ConversionRegistration.java b/hibernate-core/src/main/java/org/hibernate/boot/models/spi/ConversionRegistration.java index 69c6ba6f11..cd1383f8b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/spi/ConversionRegistration.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/spi/ConversionRegistration.java @@ -4,11 +4,8 @@ */ package org.hibernate.boot.models.spi; -import java.lang.annotation.Annotation; -import java.util.List; -import java.util.Objects; - -import org.hibernate.boot.spi.ClassmateContext; +import com.fasterxml.classmate.ResolvedType; +import jakarta.persistence.AttributeConverter; import org.hibernate.boot.model.convert.internal.AutoApplicableConverterDescriptorBypassedImpl; import org.hibernate.boot.model.convert.internal.AutoApplicableConverterDescriptorStandardImpl; import org.hibernate.boot.model.convert.internal.ConverterHelper; @@ -16,7 +13,7 @@ import org.hibernate.boot.model.convert.spi.AutoApplicableConverterDescriptor; import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext; import org.hibernate.boot.model.convert.spi.RegisteredConversion; -import org.hibernate.boot.models.Copied; +import org.hibernate.boot.spi.ClassmateContext; import org.hibernate.models.spi.AnnotationDescriptor; import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.type.descriptor.converter.internal.JpaAttributeConverterImpl; @@ -24,21 +21,21 @@ import org.hibernate.type.descriptor.converter.spi.JpaAttributeConverter; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; import org.hibernate.type.spi.TypeConfiguration; -import com.fasterxml.classmate.ResolvedType; -import jakarta.persistence.AttributeConverter; +import java.lang.annotation.Annotation; +import java.util.List; +import java.util.Objects; /** * A registered conversion. * * @see org.hibernate.annotations.ConverterRegistration * - * @todo copied from RegisteredConversion because of the "early" creation of `ConverterDescriptor` - * upstream. Technically the conversion from ClassDetails to Class should be fine since - * conversions are only valid for basic types which we will never enhance. + * @apiNote Largely a copy of {@linkplain RegisteredConversion} to avoid early creation of + * {@linkplain ConverterDescriptor}. Technically the conversion from ClassDetails to Class + * should be fine since conversions are only valid for basic types which we will never enhance. * * @author Steve Ebersole */ -@Copied(RegisteredConversion.class) public class ConversionRegistration { private final Class explicitDomainType; private final Class> converterType; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/spi/JpaEventListener.java b/hibernate-core/src/main/java/org/hibernate/boot/models/spi/JpaEventListener.java index e4ac4a445f..2a169523e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/spi/JpaEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/spi/JpaEventListener.java @@ -6,7 +6,7 @@ package org.hibernate.boot.models.spi; import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl; -import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle; +import org.hibernate.boot.models.JpaEventListenerStyle; import org.hibernate.internal.util.MutableObject; import org.hibernate.models.ModelsException; import org.hibernate.models.spi.ClassDetails; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java index 3a392a82a8..a14740147d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java @@ -118,7 +118,7 @@ import org.hibernate.boot.models.annotations.internal.UniqueConstraintJpaAnnotat import org.hibernate.boot.models.annotations.internal.UuidGeneratorAnnotation; import org.hibernate.boot.models.annotations.spi.CustomSqlDetails; import org.hibernate.boot.models.annotations.spi.DatabaseObjectDetails; -import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle; +import org.hibernate.boot.models.JpaEventListenerStyle; import org.hibernate.boot.models.spi.JpaEventListener; import org.hibernate.boot.models.xml.internal.db.ForeignKeyProcessing; import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/SourceModelTestHelper.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/SourceModelTestHelper.java index 93756cc5ad..e0826351ea 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/SourceModelTestHelper.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/SourceModelTestHelper.java @@ -31,7 +31,7 @@ import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor; import org.hibernate.boot.model.process.internal.ManagedResourcesImpl; import org.hibernate.boot.model.process.spi.ManagedResources; import org.hibernate.boot.model.process.spi.MetadataBuildingProcess; -import org.hibernate.boot.models.categorize.internal.ClassLoaderServiceLoading; +import org.hibernate.boot.models.internal.ClassLoaderServiceLoading; import org.hibernate.boot.models.internal.DomainModelCategorizationCollector; import org.hibernate.boot.models.internal.GlobalRegistrationsImpl; import org.hibernate.boot.models.internal.ModelsHelper; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/globals/JpaEventListenerTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/globals/JpaEventListenerTests.java index c2967281fd..bcbce94ff7 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/globals/JpaEventListenerTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/xml/globals/JpaEventListenerTests.java @@ -4,23 +4,27 @@ */ package org.hibernate.orm.test.boot.models.xml.globals; -import java.util.List; - import org.hibernate.boot.internal.BootstrapContextImpl; +import org.hibernate.boot.internal.InFlightMetadataCollectorImpl; import org.hibernate.boot.internal.MetadataBuilderImpl; +import org.hibernate.boot.internal.MetadataBuildingContextRootImpl; import org.hibernate.boot.model.process.spi.ManagedResources; +import org.hibernate.boot.model.process.spi.MetadataBuildingProcess; import org.hibernate.boot.model.source.internal.annotations.AdditionalManagedResourcesImpl; -import org.hibernate.boot.models.categorize.spi.CategorizedDomainModel; +import org.hibernate.boot.model.source.internal.annotations.DomainModelSource; import org.hibernate.boot.models.spi.JpaEventListener; import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.models.spi.MethodDetails; - import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistryScope; import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; -import static org.hibernate.boot.models.categorize.spi.ManagedResourcesProcessor.processManagedResources; +import static org.hibernate.boot.model.process.spi.MetadataBuildingProcess.coordinateProcessors; import static org.hibernate.models.spi.ClassDetails.VOID_CLASS_DETAILS; /** @@ -35,25 +39,61 @@ public class JpaEventListenerTests { .addXmlMappings( "mappings/models/globals.xml" ) .build(); - final StandardServiceRegistry serviceRegistry = registryScope.getRegistry(); - final BootstrapContextImpl bootstrapContext = new BootstrapContextImpl( - serviceRegistry, - new MetadataBuilderImpl.MetadataBuildingOptionsImpl( serviceRegistry ) - ); - final CategorizedDomainModel categorizedDomainModel = processManagedResources( - managedResources, - bootstrapContext - ); - final List registrations = categorizedDomainModel - .getGlobalRegistrations() - .getEntityListenerRegistrations(); + final InFlightMetadataCollector metadataCollector = buildMetadataCollector( managedResources, registryScope ); + final List registrations = metadataCollector.getGlobalRegistrations().getEntityListenerRegistrations(); assertThat( registrations ).hasSize( 1 ); final JpaEventListener registration = registrations.get( 0 ); final MethodDetails postPersistMethod = registration.getPostPersistMethod(); assertThat( postPersistMethod ).isNotNull(); assertThat( postPersistMethod.getReturnType() ).isEqualTo( VOID_CLASS_DETAILS ); assertThat( postPersistMethod.getArgumentTypes() ).hasSize( 1 ); - } + private InFlightMetadataCollector buildMetadataCollector(ManagedResources managedResources, ServiceRegistryScope registryScope) { + final StandardServiceRegistry serviceRegistry = registryScope.getRegistry(); + + final ClassLoaderService classLoaderService = serviceRegistry.requireService( ClassLoaderService.class ); + assert classLoaderService != null; + + final MetadataBuilderImpl.MetadataBuildingOptionsImpl options = new MetadataBuilderImpl.MetadataBuildingOptionsImpl( serviceRegistry ); + final BootstrapContextImpl bootstrapContext = new BootstrapContextImpl( serviceRegistry, options ); + options.setBootstrapContext( bootstrapContext ); + final InFlightMetadataCollectorImpl metadataCollector = new InFlightMetadataCollectorImpl( bootstrapContext, options ); + + final DomainModelSource domainModelSource = MetadataBuildingProcess.processManagedResources( + managedResources, + metadataCollector, + bootstrapContext, + options.getMappingDefaults() + ); + + + final MetadataBuildingContextRootImpl rootMetadataBuildingContext = new MetadataBuildingContextRootImpl( + "orm", + bootstrapContext, + options, + metadataCollector, + domainModelSource.getEffectiveMappingDefaults() + ); + + managedResources.getAttributeConverterDescriptors().forEach( metadataCollector::addAttributeConverter ); + + bootstrapContext.getTypeConfiguration().scope( rootMetadataBuildingContext ); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Set up the processors and start binding + // NOTE : this becomes even more simplified after we move purely + // to unified model +// final IndexView jandexView = domainModelSource.getJandexIndex(); + + coordinateProcessors( + managedResources, + options, + rootMetadataBuildingContext, + domainModelSource, + metadataCollector + ); + + return metadataCollector; + } }