From 0caa0d15624f8773bb3412be60f76352ba150e36 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Tue, 20 Aug 2024 12:54:43 +0200 Subject: [PATCH 1/2] HHH-18506 Improve flush performance by reducing itable stubs --- .../HibernateTraversableResolver.java | 11 +++-- ...EnhancementAsProxyLazinessInterceptor.java | 3 +- .../interceptor/LazyAttributeDescriptor.java | 3 +- .../hibernate/engine/internal/Cascade.java | 27 ++++++------ .../engine/internal/ForeignKeys.java | 21 ++++----- .../engine/internal/Nullability.java | 15 ++++--- .../engine/profile/FetchProfile.java | 3 +- .../org/hibernate/engine/spi/ActionQueue.java | 13 +++--- .../engine/spi/CascadingActions.java | 2 +- .../event/internal/AbstractVisitor.java | 13 ++++-- .../internal/DefaultDeleteEventListener.java | 9 ++-- .../internal/DefaultMergeEventListener.java | 15 ++++--- .../internal/DefaultRefreshEventListener.java | 8 ++-- .../org/hibernate/id/ForeignGenerator.java | 2 +- .../java/org/hibernate/mapping/Property.java | 27 +++++++++--- .../metamodel/internal/AttributeFactory.java | 43 ++++++++++--------- .../internal/BaseAttributeMetadata.java | 3 +- .../AbstractEntityCollectionPart.java | 9 ++-- .../mapping/internal/FetchOptionsHelper.java | 11 +++-- .../internal/MappingModelCreationHelper.java | 2 +- .../internal/ToOneAttributeMapping.java | 12 +++--- .../domain/internal/MappingMetamodelImpl.java | 4 +- .../AbstractCollectionPersister.java | 12 +++--- .../collection/BasicCollectionPersister.java | 3 +- .../entity/AbstractEntityPersister.java | 11 ++--- .../entity/AbstractPropertyMapping.java | 21 +++++++-- .../internal/ResultSetMappingProcessor.java | 8 ++-- .../sql/results/internal/ResultsHelper.java | 3 +- .../org/hibernate/tuple/PropertyFactory.java | 29 +++++++------ .../tuple/entity/EntityMetamodel.java | 4 +- .../org/hibernate/type/CollectionType.java | 2 +- .../java/org/hibernate/type/EntityType.java | 6 +-- .../java/org/hibernate/type/TypeHelper.java | 8 ++-- .../relation/BasicCollectionMapper.java | 2 +- .../internal/ValidityAuditStrategy.java | 2 +- 35 files changed, 219 insertions(+), 148 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/HibernateTraversableResolver.java b/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/HibernateTraversableResolver.java index 1058a19823e5..c0afa9d0dc1d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/HibernateTraversableResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/HibernateTraversableResolver.java @@ -15,8 +15,11 @@ import org.hibernate.Hibernate; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.AnyType; import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; +import org.hibernate.type.EntityType; import org.hibernate.type.Type; import jakarta.validation.Path; @@ -54,17 +57,17 @@ private void addAssociationsToTheSetForAllProperties(String[] names, Type[] type private void addAssociationsToTheSetForOneProperty(String name, Type type, String prefix, SessionFactoryImplementor factory) { - if ( type.isCollectionType() ) { + if ( type instanceof CollectionType ) { CollectionType collType = (CollectionType) type; Type assocType = collType.getElementType( factory ); addAssociationsToTheSetForOneProperty(name, assocType, prefix, factory); } //ToOne association - else if ( type.isEntityType() || type.isAnyType() ) { + else if ( type instanceof EntityType || type instanceof AnyType ) { associations.add( prefix + name ); } - else if ( type.isComponentType() ) { - CompositeType componentType = (CompositeType) type; + else if ( type instanceof ComponentType ) { + ComponentType componentType = (ComponentType) type; addAssociationsToTheSetForAllProperties( componentType.getPropertyNames(), componentType.getSubtypes(), diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java index 50f3d26bafa5..0c601b2d6c13 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java @@ -19,6 +19,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.CollectionType; import org.hibernate.type.CompositeType; import org.hibernate.type.Type; @@ -67,7 +68,7 @@ public EnhancementAsProxyLazinessInterceptor( collectionAttributeNames = new HashSet<>(); for ( int i = 0; i < propertyTypes.length; i++ ) { Type propertyType = propertyTypes[i]; - if ( propertyType.isCollectionType() ) { + if ( propertyType instanceof CollectionType ) { collectionAttributeNames.add( entityPersister.getPropertyNames()[i] ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/LazyAttributeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/LazyAttributeDescriptor.java index 0a2b54aff487..8f0ba8647737 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/LazyAttributeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/LazyAttributeDescriptor.java @@ -7,6 +7,7 @@ package org.hibernate.bytecode.enhance.spi.interceptor; import org.hibernate.mapping.Property; +import org.hibernate.type.CollectionType; import org.hibernate.type.Type; /** @@ -21,7 +22,7 @@ public static LazyAttributeDescriptor from( int lazyIndex) { String fetchGroupName = property.getLazyGroup(); if ( fetchGroupName == null ) { - fetchGroupName = property.getType().isCollectionType() + fetchGroupName = property.getType() instanceof CollectionType ? property.getName() : "DEFAULT"; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java index 2342b0f6c016..37d38aaf5ca6 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java @@ -28,12 +28,14 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.HibernateProxy; +import org.hibernate.type.AnyType; import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.ForeignKeyDirection; +import org.hibernate.type.OneToOneType; import org.hibernate.type.Type; import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy; @@ -125,7 +127,7 @@ public static void cascade( // parent was not in the PersistenceContext continue; } - if ( type.isCollectionType() ) { + if ( type instanceof CollectionType ) { // CollectionType#getCollection gets the PersistentCollection // that corresponds to the uninitialized collection from the // PersistenceContext. If not present, an uninitialized @@ -140,13 +142,13 @@ public static void cascade( null ); } - else if ( type.isComponentType() ) { + else if ( type instanceof AnyType || type instanceof ComponentType ) { // Hibernate does not support lazy embeddables, so this shouldn't happen. throw new UnsupportedOperationException( "Lazy components are not supported." ); } - else if ( action.performOnLazyProperty() && type.isEntityType() ) { + else if ( action.performOnLazyProperty() && type instanceof EntityType ) { // Only need to initialize a lazy entity attribute when action.performOnLazyProperty() // returns true. LazyAttributeLoadingInterceptor interceptor = persister.getBytecodeEnhancementMetadata() @@ -226,7 +228,7 @@ private static void cascadeProperty( final boolean isCascadeDeleteEnabled) throws HibernateException { if ( child != null ) { - if ( type.isAssociationType() ) { + if ( type instanceof EntityType || type instanceof CollectionType || type instanceof AnyType ) { final AssociationType associationType = (AssociationType) type; if ( cascadeAssociationNow( cascadePoint, associationType ) ) { cascadeAssociation( @@ -243,7 +245,7 @@ private static void cascadeProperty( ); } } - else if ( type.isComponentType() ) { + else if ( type instanceof ComponentType ) { if ( componentPath == null && propertyName != null ) { componentPath = new ArrayList<>(); } @@ -358,9 +360,8 @@ private static void cascadeLogicalOneToOneOrphanRemoval( LOG.tracev( "Deleting orphaned entity instance: {0}", description ); } - if ( type.isAssociationType() && ( (AssociationType) type ).getForeignKeyDirection().equals( - ForeignKeyDirection.TO_PARENT - ) ) { + if ( type instanceof CollectionType + || type instanceof OneToOneType && ( (OneToOneType) type ).getForeignKeyDirection() == ForeignKeyDirection.TO_PARENT ) { // If FK direction is to-parent, we must remove the orphan *before* the queued update(s) // occur. Otherwise, replacing the association on a managed entity, without manually // nulling and flushing, causes FK constraint violations. @@ -442,10 +443,10 @@ private static void cascadeAssociation( final CascadeStyle style, final T anything, final boolean isCascadeDeleteEnabled) { - if ( type.isEntityType() || type.isAnyType() ) { + if ( type instanceof EntityType || type instanceof AnyType ) { cascadeToOne( action, eventSource, parent, child, type, style, anything, isCascadeDeleteEnabled ); } - else if ( type.isCollectionType() ) { + else if ( type instanceof CollectionType ) { cascadeCollection( action, cascadePoint, @@ -485,7 +486,7 @@ private static void cascadeCollection( } //cascade to current collection elements - if ( elemType.isEntityType() || elemType.isAnyType() || elemType.isComponentType() ) { + if ( elemType instanceof EntityType || elemType instanceof AnyType || elemType instanceof ComponentType ) { cascadeCollectionElements( action, elementsCascadePoint, @@ -514,7 +515,7 @@ private static void cascadeToOne( final CascadeStyle style, final T anything, final boolean isCascadeDeleteEnabled) { - final String entityName = type.isEntityType() + final String entityName = type instanceof EntityType ? ( (EntityType) type ).getAssociatedEntityName() : null; if ( style.reallyDoCascade( action ) ) { @@ -578,7 +579,7 @@ private static void cascadeCollectionElements( final boolean deleteOrphans = style.hasOrphanDelete() && action.deleteOrphans() - && elemType.isEntityType() + && elemType instanceof EntityType && child instanceof PersistentCollection // a newly instantiated collection can't have orphans && ! ( (PersistentCollection) child ).isNewlyInstantiated(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/ForeignKeys.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/ForeignKeys.java index dfaffa7a1cac..0110279dd7c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/ForeignKeys.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/ForeignKeys.java @@ -17,7 +17,8 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; -import org.hibernate.type.CompositeType; +import org.hibernate.type.AnyType; +import org.hibernate.type.ComponentType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -91,7 +92,7 @@ private Object nullifyTransientReferences(final Object value, final String prope if ( value == null ) { returnedValue = null; } - else if ( type.isEntityType() ) { + else if ( type instanceof EntityType ) { final EntityType entityType = (EntityType) type; if ( entityType.isOneToOne() ) { returnedValue = value; @@ -113,11 +114,11 @@ else if ( type.isEntityType() ) { } } } - else if ( type.isAnyType() ) { + else if ( type instanceof AnyType ) { returnedValue = isNullifiable( null, value ) ? null : value; } - else if ( type.isComponentType() ) { - final CompositeType actype = (CompositeType) type; + else if ( type instanceof ComponentType ) { + final ComponentType actype = (ComponentType) type; final Object[] subvalues = actype.getPropertyValues( value, session ); final Type[] subtypes = actype.getSubtypes(); final String[] subPropertyNames = actype.getPropertyNames(); @@ -159,7 +160,7 @@ private Object initializeIfNecessary( final Type type) { if ( isDelete && value == LazyPropertyInitializer.UNFETCHED_PROPERTY && - type.isEntityType() && + type instanceof EntityType && !session.getPersistenceContextInternal().isNullifiableEntityKeysEmpty() ) { // IMPLEMENTATION NOTE: If cascade-remove was mapped for the attribute, // then value should have been initialized previously, when the remove operation was @@ -406,7 +407,7 @@ private static void collectNonNullableTransientEntities( return; } - if ( type.isEntityType() ) { + if ( type instanceof EntityType ) { final EntityType entityType = (EntityType) type; if ( !isNullable && !entityType.isOneToOne() @@ -414,13 +415,13 @@ private static void collectNonNullableTransientEntities( nonNullableTransientEntities.add( propertyName, value ); } } - else if ( type.isAnyType() ) { + else if ( type instanceof AnyType ) { if ( !isNullable && nullifier.isNullifiable( null, value ) ) { nonNullableTransientEntities.add( propertyName, value ); } } - else if ( type.isComponentType() ) { - final CompositeType actype = (CompositeType) type; + else if ( type instanceof ComponentType ) { + final ComponentType actype = (ComponentType) type; final boolean[] subValueNullability = actype.getPropertyNullability(); if ( subValueNullability != null ) { final String[] subPropertyNames = actype.getPropertyNames(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/Nullability.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/Nullability.java index 468ba0d92b85..284d15499348 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/Nullability.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/Nullability.java @@ -15,7 +15,9 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.generator.Generator; +import org.hibernate.type.AnyType; import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.Type; @@ -143,16 +145,19 @@ private static boolean generated(Generator generator) { * @throws HibernateException error while getting subcomponent values */ private String checkSubElementsNullability(Type propertyType, Object value) throws HibernateException { - if ( propertyType.isComponentType() ) { - return checkComponentNullability( value, (CompositeType) propertyType ); + if ( propertyType instanceof AnyType ) { + return checkComponentNullability( value, (AnyType) propertyType ); + } + if ( propertyType instanceof ComponentType ) { + return checkComponentNullability( value, (ComponentType) propertyType ); } - if ( propertyType.isCollectionType() ) { + if ( propertyType instanceof CollectionType ) { // persistent collections may have components final CollectionType collectionType = (CollectionType) propertyType; final Type collectionElementType = collectionType.getElementType( session.getFactory() ); - if ( collectionElementType.isComponentType() ) { + if ( collectionElementType instanceof ComponentType || collectionElementType instanceof AnyType ) { // check for all components values in the collection final CompositeType componentType = (CompositeType) collectionElementType; final Iterator itr = CascadingActions.getLoadedElementsIterator( session, collectionType, value ); @@ -188,7 +193,7 @@ private String checkComponentNullability(Object value, CompositeType compositeTy // // The more correct fix would be to cascade saves of the many-to-any elements before the Nullability checking - if ( compositeType.isAnyType() ) { + if ( compositeType instanceof AnyType ) { return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java index 4e48e335e66c..12a9fcc428f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java @@ -12,6 +12,7 @@ import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.type.BagType; +import org.hibernate.type.CollectionType; import org.hibernate.type.Type; /** @@ -82,7 +83,7 @@ public void addFetch(Association association, Fetch.Style style) { public void addFetch(final Fetch fetch) { final String fetchAssociactionRole = fetch.getAssociation().getRole(); final Type associationType = fetch.getAssociation().getOwner().getPropertyType( fetch.getAssociation().getAssociationPath() ); - if ( associationType.isCollectionType() ) { + if ( associationType instanceof CollectionType ) { LOG.tracev( "Handling request to add collection fetch [{0}]", fetchAssociactionRole ); // couple of things for which to account in the case of collection diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java index b5567e47cc59..8cca8373e6fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java @@ -53,7 +53,7 @@ import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; import org.hibernate.type.CollectionType; -import org.hibernate.type.CompositeType; +import org.hibernate.type.ComponentType; import org.hibernate.type.EntityType; import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.OneToOneType; @@ -1151,7 +1151,10 @@ public void addTransitiveDependencies(InsertInfo origin, Set visited } private void addDirectDependency(Type type, Object value, IdentityHashMap insertInfosByEntity) { - if ( type.isEntityType() && value != null ) { + if ( value == null ) { + return; + } + if ( type instanceof EntityType ) { final EntityType entityType = (EntityType) type; final InsertInfo insertInfo = insertInfosByEntity.get(value); if (insertInfo != null) { @@ -1171,7 +1174,7 @@ private void addDirectDependency(Type type, Object value, IdentityHashMap cache.unlockItem( session, ck, lock ) ); } } - else if ( type.isComponentType() ) { - CompositeType compositeType = (CompositeType) type; + else if ( type instanceof ComponentType ) { + // Only components can contain collections + ComponentType compositeType = (ComponentType) type; evictCachedCollections( compositeType.getSubtypes(), id, source ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/ForeignGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/ForeignGenerator.java index 43e0314a8c04..9a9c116b0f3d 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/ForeignGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/ForeignGenerator.java @@ -100,7 +100,7 @@ public Object generate(SharedSessionContractImplementor sessionImplementor, Obje final EntityType foreignValueSourceType; final Type propertyType = entityDescriptor.getPropertyType( propertyName ); - if ( propertyType.isEntityType() ) { + if ( propertyType instanceof EntityType ) { // the normal case foreignValueSourceType = (EntityType) propertyType; } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Property.java b/hibernate-core/src/main/java/org/hibernate/mapping/Property.java index ac76167d22f5..df04313477f3 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Property.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Property.java @@ -32,6 +32,9 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.generator.Generator; import org.hibernate.generator.GeneratorCreationContext; +import org.hibernate.type.AnyType; +import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.Type; import org.hibernate.type.WrapperArrayHandling; @@ -150,10 +153,13 @@ public boolean isPrimitive(Class clazz) { public CascadeStyle getCascadeStyle() throws MappingException { final Type type = value.getType(); - if ( type.isComponentType() ) { - return getCompositeCascadeStyle( (CompositeType) type, cascade ); + if ( type instanceof AnyType ) { + return getCascadeStyle( cascade ); + } + if ( type instanceof ComponentType ) { + return getCompositeCascadeStyle( (ComponentType) type, cascade ); } - else if ( type.isCollectionType() ) { + else if ( type instanceof CollectionType ) { return getCollectionCascadeStyle( ( (Collection) value ).getElement().getType(), cascade ); } else { @@ -162,9 +168,15 @@ else if ( type.isCollectionType() ) { } private static CascadeStyle getCompositeCascadeStyle(CompositeType compositeType, String cascade) { - if ( compositeType.isAnyType() ) { + if ( compositeType instanceof AnyType ) { return getCascadeStyle( cascade ); } + else { + return getCompositeCascadeStyle( (ComponentType) compositeType, cascade ); + } + } + + private static CascadeStyle getCompositeCascadeStyle(ComponentType compositeType, String cascade) { int length = compositeType.getSubtypes().length; for ( int i=0; i AttributeMetadata determineAttributeMetadata( final org.hibernate.type.Type type = value.getType(); LOG.tracef( " Determined type [name=%s, class=%s]", type.getName(), type.getClass().getName() ); - if ( type.isAnyType() ) { + if ( type instanceof AnyType ) { return new SingularAttributeMetadataImpl<>( propertyMapping, attributeContext.getOwnerType(), @@ -418,18 +421,17 @@ private static AttributeMetadata determineAttributeMetadata( context ); } - else if ( type.isAssociationType() ) { - // collection or entity - if ( type.isEntityType() ) { - // entity - return new SingularAttributeMetadataImpl<>( - propertyMapping, - attributeContext.getOwnerType(), - member, - determineSingularAssociationClassification( member ), - context - ); - } + else if ( type instanceof EntityType ) { + // entity + return new SingularAttributeMetadataImpl<>( + propertyMapping, + attributeContext.getOwnerType(), + member, + determineSingularAssociationClassification( member ), + context + ); + } + else if ( type instanceof CollectionType ) { // collection if ( value instanceof Collection ) { final Collection collValue = (Collection) value; @@ -441,15 +443,15 @@ else if ( type.isAssociationType() ) { // collection type final AttributeClassification elementClassification; final AttributeClassification attributeClassification; - if ( elementType.isAnyType() ) { + if ( elementType instanceof AnyType ) { attributeClassification = AttributeClassification.ELEMENT_COLLECTION; elementClassification = AttributeClassification.ANY; } - else if ( elementValue instanceof Component ) { + else if ( elementType instanceof ComponentType ) { elementClassification = AttributeClassification.EMBEDDED; attributeClassification = AttributeClassification.ELEMENT_COLLECTION; } - else if ( elementType.isAssociationType() ) { + else if ( elementType instanceof EntityType ) { elementClassification = isManyToMany ? AttributeClassification.MANY_TO_MANY : AttributeClassification.ONE_TO_MANY; @@ -467,13 +469,13 @@ else if ( elementType.isAssociationType() ) { final Value keyValue = ( (Map) value ).getIndex(); final org.hibernate.type.Type keyType = keyValue.getType(); - if ( keyType.isAnyType() ) { + if ( keyType instanceof AnyType ) { indexClassification = AttributeClassification.ANY; } - else if ( keyValue instanceof Component ) { + else if ( keyType instanceof ComponentType ) { indexClassification = AttributeClassification.EMBEDDED; } - else if ( keyType.isAssociationType() ) { + else if ( keyType instanceof EntityType ) { indexClassification = AttributeClassification.MANY_TO_ONE; } else { @@ -516,7 +518,7 @@ else if ( value instanceof OneToMany ) { // ); } } - else if ( propertyMapping.isComposite() ) { + else if ( type instanceof ComponentType ) { // component return new SingularAttributeMetadataImpl<>( propertyMapping, @@ -527,6 +529,7 @@ else if ( propertyMapping.isComposite() ) { ); } else { + assert type instanceof BasicType; // basic type return new SingularAttributeMetadataImpl<>( propertyMapping, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java index 18f833728c58..b7602f1c16a1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java @@ -14,6 +14,7 @@ import org.hibernate.metamodel.AttributeClassification; import org.hibernate.metamodel.model.domain.ManagedDomainType; import org.hibernate.metamodel.model.domain.internal.MapMember; +import org.hibernate.type.CollectionType; /** * @author Steve Ebersole @@ -88,7 +89,7 @@ public ManagedDomainType getOwnerType() { } public boolean isPlural() { - return propertyMapping.getType().isCollectionType(); + return propertyMapping.getType() instanceof CollectionType; } public Property getPropertyMapping() { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java index 88266080cc17..f32b26059bea 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java @@ -47,6 +47,7 @@ import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch; import org.hibernate.sql.results.graph.entity.EntityFetch; import org.hibernate.sql.results.graph.entity.internal.EntityFetchJoinedImpl; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.Type; @@ -382,8 +383,8 @@ private static Set resolveTargetKeyPropertyNames( propertyType = entityBinding.getIdentifierMapper().getType(); } if ( entityBinding.getIdentifierProperty() == null ) { - final CompositeType compositeType; - if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() + final ComponentType compositeType; + if ( propertyType instanceof ComponentType && ( compositeType = (ComponentType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { ToOneAttributeMapping.addPrefixedPropertyPaths( targetKeyPropertyNames, @@ -436,8 +437,8 @@ else if ( bootModelValue instanceof OneToMany ) { } else { final Type propertyType = entityBinding.getRecursiveProperty( referencedPropertyName ).getType(); - final CompositeType compositeType; - if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() + final ComponentType compositeType; + if ( propertyType instanceof ComponentType && ( compositeType = (ComponentType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { final Set targetKeyPropertyNames = new HashSet<>( 2 ); ToOneAttributeMapping.addPrefixedPropertyPaths( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/FetchOptionsHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/FetchOptionsHelper.java index 421a37ada573..aef5a230fd06 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/FetchOptionsHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/FetchOptionsHelper.java @@ -16,7 +16,10 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.sql.results.graph.FetchOptions; +import org.hibernate.type.AnyType; import org.hibernate.type.AssociationType; +import org.hibernate.type.CollectionType; +import org.hibernate.type.EntityType; /** * @author Steve Ebersole @@ -40,7 +43,7 @@ public static FetchStyle determineFetchStyleByMetadata( FetchMode mappingFetchMode, AssociationType type, SessionFactoryImplementor sessionFactory) { - if ( !type.isEntityType() && !type.isCollectionType() ) { + if ( !( type instanceof EntityType ) && !( type instanceof CollectionType ) ) { return FetchStyle.SELECT; } @@ -48,7 +51,7 @@ public static FetchStyle determineFetchStyleByMetadata( return FetchStyle.JOIN; } - if ( type.isEntityType() ) { + if ( type instanceof EntityType ) { EntityPersister persister = (EntityPersister) type.getAssociatedJoinable( sessionFactory ); if ( persister.isBatchLoadable() ) { return FetchStyle.BATCH; @@ -116,11 +119,11 @@ public static FetchTiming determineFetchTiming( } private static boolean isSubsequentSelectDelayed(AssociationType type, SessionFactoryImplementor sessionFactory) { - if ( type.isAnyType() ) { + if ( type instanceof AnyType ) { // we'd need more context here. this is only kept as part of the property state on the owning entity return false; } - else if ( type.isEntityType() ) { + else if ( type instanceof EntityType ) { final EntityPersister entityPersister = (EntityPersister) type.getAssociatedJoinable( sessionFactory ); return entityPersister.getEntityMetamodel().isLazy(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java index 5b5c4e3dee0c..d8c0fed987c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java @@ -743,7 +743,7 @@ private static void interpretPluralAttributeMappingKeyDescriptor( final ManagedMappingType keyDeclaringType; final String collectionTableName = ((AbstractCollectionPersister) collectionDescriptor).getTableName(); - if ( collectionDescriptor.getElementType().isEntityType() ) { + if ( collectionDescriptor.getElementType() instanceof EntityType ) { keyDeclaringType = ( (QueryableCollection) collectionDescriptor ).getElementPersister(); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java index 7375dfbe9f8c..26c600a3fbe1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java @@ -427,8 +427,8 @@ the navigable path is NavigablePath(Card.fields.{element}.{id}.card) and it does propertyType = entityBinding.getIdentifierMapper().getType(); } if ( entityBinding.getIdentifierProperty() == null ) { - final CompositeType compositeType; - if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() + final ComponentType compositeType; + if ( propertyType instanceof ComponentType && ( compositeType = (ComponentType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { this.targetKeyPropertyName = compositeType.getPropertyNames()[0]; addPrefixedPropertyPaths( @@ -487,8 +487,8 @@ the navigable path is NavigablePath(Card.fields.{element}.{id}.card) and it does this.targetKeyPropertyNames = targetKeyPropertyNames; } else { - final CompositeType compositeType; - if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() + final ComponentType compositeType; + if ( propertyType instanceof ComponentType && ( compositeType = (ComponentType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { final Set targetKeyPropertyNames = new HashSet<>( 2 ); this.targetKeyPropertyName = compositeType.getPropertyNames()[0]; @@ -737,7 +737,7 @@ public static void addPrefixedPropertyNames( if ( prefix != null ) { targetKeyPropertyNames.add( prefix ); } - if ( type.isComponentType() ) { + if ( type instanceof ComponentType ) { final ComponentType componentType = (ComponentType) type; final String[] propertyNames = componentType.getPropertyNames(); final Type[] componentTypeSubtypes = componentType.getSubtypes(); @@ -752,7 +752,7 @@ public static void addPrefixedPropertyNames( addPrefixedPropertyNames( targetKeyPropertyNames, newPrefix, componentTypeSubtypes[i], factory ); } } - else if ( type.isEntityType() ) { + else if ( type instanceof EntityType ) { final EntityType entityType = (EntityType) type; final Type identifierOrUniqueKeyType = entityType.getIdentifierOrUniqueKeyType( factory ); final String propertyName; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java index 640d6aa7ec25..779fba05c015 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappingMetamodelImpl.java @@ -314,7 +314,7 @@ private void processBootCollections( ); collectionPersisterMap.put( model.getRole(), persister ); Type indexType = persister.getIndexType(); - if ( indexType != null && indexType.isEntityType() && !indexType.isAnyType() ) { + if ( indexType instanceof org.hibernate.type.EntityType ) { String entityName = ( (org.hibernate.type.EntityType) indexType ).getAssociatedEntityName(); Set roles = collectionRolesByEntityParticipant.get( entityName ); //noinspection Java8MapApi @@ -325,7 +325,7 @@ private void processBootCollections( roles.add( persister.getRole() ); } Type elementType = persister.getElementType(); - if ( elementType.isEntityType() && !elementType.isAnyType() ) { + if ( elementType instanceof org.hibernate.type.EntityType ) { String entityName = ( (org.hibernate.type.EntityType) elementType ).getAssociatedEntityName(); Set roles = collectionRolesByEntityParticipant.get( entityName ); //noinspection Java8MapApi diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index aa7e8bb3aadb..5a1cd22bcce8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -128,7 +128,9 @@ import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; import org.hibernate.sql.results.internal.SqlSelectionImpl; +import org.hibernate.type.AnyType; import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -336,7 +338,7 @@ public AbstractCollectionPersister( // ELEMENT - if ( elementType.isEntityType() ) { + if ( elementType instanceof EntityType ) { String entityName = ( (EntityType) elementType ).getAssociatedEntityName(); elementPersister = creationContext.getDomainModel().getEntityDescriptor( entityName ); // NativeSQL: collect element column and auto-aliases @@ -387,7 +389,7 @@ public AbstractCollectionPersister( creationContext.getFunctionRegistry() ); elementColumnIsGettable[j] = true; - if ( elementType.isComponentType() ) { + if ( elementType instanceof ComponentType || elementType instanceof AnyType ) { // Implements desired behavior specifically for @ElementCollection mappings. elementColumnIsSettable[j] = columnInsertability[j]; } @@ -503,7 +505,7 @@ else if ( indexedCollection instanceof org.hibernate.mapping.Map elementClass = null; // elementType.returnedClass(); } - if ( elementType.isComponentType() ) { + if ( elementType instanceof ComponentType || elementType instanceof AnyType ) { elementPropertyMapping = new CompositeElementPropertyMapping( elementColumnNames, elementColumnReaders, @@ -513,7 +515,7 @@ else if ( indexedCollection instanceof org.hibernate.mapping.Map creationContext.getMetadata() ); } - else if ( !elementType.isEntityType() ) { + else if ( !( elementType instanceof EntityType ) ) { elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType ); } else { @@ -1411,7 +1413,7 @@ private void initCollectionPropertyMap(String aliasName, Type type, String[] col collectionPropertyColumnAliases.put( aliasName, columnAliases ); //TODO: this code is almost certainly obsolete and can be removed - if ( type.isComponentType() ) { + if ( type instanceof ComponentType || type instanceof AnyType ) { CompositeType ct = (CompositeType) type; String[] propertyNames = ct.getPropertyNames(); for ( int i = 0; i < propertyNames.length; i++ ) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java index 8c7c729eec95..5c8387bdceb4 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java @@ -51,6 +51,7 @@ import org.hibernate.sql.model.ast.builder.TableInsertBuilderStandard; import org.hibernate.sql.model.ast.builder.TableUpdateBuilderStandard; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; +import org.hibernate.type.EntityType; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; @@ -701,7 +702,7 @@ public boolean isOneToMany() { @Override public boolean isManyToMany() { - return elementType.isEntityType(); //instanceof AssociationType; + return elementType instanceof EntityType; //instanceof AssociationType; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index c3a216872589..a6e2686e6c56 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -283,6 +283,7 @@ import org.hibernate.type.AssociationType; import org.hibernate.type.BasicType; import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -902,7 +903,7 @@ else if ( entityMetamodel.isMutable() ) { // 2) have no associations. // Eventually we want to be a little more lenient with associations. for ( Type type : getSubclassPropertyTypeClosure() ) { - if ( type.isAssociationType() ) { + if ( type instanceof AnyType || type instanceof CollectionType || type instanceof EntityType ) { return false; } } @@ -1445,7 +1446,7 @@ public Object initializeLazyProperty(String fieldName, Object entity, SharedSess if ( hasCollections() ) { final Type type = getPropertyType( fieldName ); - if ( type.isCollectionType() ) { + if ( type instanceof CollectionType ) { // we have a condition where a collection attribute is being access via enhancement: // we can circumvent all the rest and just return the PersistentCollection final CollectionType collectionType = (CollectionType) type; @@ -2245,7 +2246,7 @@ public int getSubclassPropertyTableNumber(String propertyPath) { // // performance op to avoid the array search // return 0; // } -// else if ( type.isCollectionType() ) { +// else if ( type instanceof CollectionType ) { // // properly handle property-ref-based associations // rootPropertyName = assocType.getLHSPropertyName(); // } @@ -6444,9 +6445,9 @@ public String[] getSubclassPropertyColumnAliases(String propertyName, String suf } // aliases for composite-id's - if ( getIdentifierType().isComponentType() ) { + if ( getIdentifierType() instanceof ComponentType ) { // Fetch embedded identifiers property names from the "virtual" identifier component - final CompositeType componentId = (CompositeType) getIdentifierType(); + final ComponentType componentId = (ComponentType) getIdentifierType(); final String[] idPropertyNames = componentId.getPropertyNames(); final String[] idAliases = getIdentifierAliases(); final String[] idColumnNames = getIdentifierColumnNames(); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java index 2470ed0a1b72..4c3cbea73bf3 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java @@ -27,6 +27,7 @@ import org.hibernate.type.AnyType; import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.ManyToOneType; @@ -282,7 +283,7 @@ protected void initPropertyPaths( ); } - if ( type.isAssociationType() ) { + if ( type instanceof AnyType || type instanceof CollectionType || type instanceof EntityType ) { AssociationType actype = (AssociationType) type; if ( actype.useLHSPrimaryKey() ) { columns = getIdentifierColumnNames(); @@ -308,8 +309,20 @@ protected void initPropertyPaths( addPropertyPath( path, type, columns, columnReaders, columnReaderTemplates, formulaTemplates, factory ); } - if ( type.isComponentType() ) { - CompositeType actype = (CompositeType) type; + if ( type instanceof AnyType ) { + AnyType actype = (AnyType) type; + initComponentPropertyPaths( + path, + actype, + columns, + columnReaders, + columnReaderTemplates, + formulaTemplates, + factory + ); + } + else if ( type instanceof ComponentType ) { + ComponentType actype = (ComponentType) type; initComponentPropertyPaths( path, actype, @@ -331,7 +344,7 @@ protected void initPropertyPaths( ); } } - else if ( type.isEntityType() ) { + else if ( type instanceof EntityType ) { initIdentifierPropertyPaths( path, (EntityType) type, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java index c4100379067f..38ad1ddd2c22 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java @@ -409,7 +409,7 @@ private CompleteResultBuilderCollectionStandard createSuffixedResultBuilder( String entitySuffix) { final CollectionPersister collectionPersister = collectionReturn.getPluralAttribute().getCollectionDescriptor(); final String[] elementColumnAliases; - if ( collectionPersister.getElementType().isEntityType() ) { + if ( collectionPersister.getElementType() instanceof EntityType ) { final Loadable elementPersister = (Loadable) ( ( QueryableCollection ) collectionPersister).getElementPersister(); final String[] propertyNames = elementPersister.getPropertyNames(); final String[] identifierAliases = elementPersister.getIdentifierAliases( entitySuffix ); @@ -568,13 +568,13 @@ private void processFetchReturn(NativeQuery.FetchReturn fetchReturn) { SQLLoadable ownerPersister = ( SQLLoadable ) alias2Persister.get( ownerAlias ); Type returnType = ownerPersister.getPropertyType( fetchReturn.getFetchableName() ); - if ( returnType.isCollectionType() ) { + if ( returnType instanceof CollectionType ) { String role = ownerPersister.getEntityName() + '.' + fetchReturn.getFetchableName(); Map propertyResultsMap = Collections.emptyMap();//fetchReturn.getPropertyResultsMap() addCollection( role, alias, propertyResultsMap ); // collectionOwnerAliases.add( ownerAlias ); } - else if ( returnType.isEntityType() ) { + else if ( returnType instanceof EntityType ) { EntityType eType = ( EntityType ) returnType; String returnEntityName = eType.getAssociatedEntityName(); SQLLoadable persister = getSQLLoadable( returnEntityName ); @@ -634,7 +634,7 @@ public Map getPropertyResultsMap(String alias) { // } // for ( CollectionPersister persister : alias2CollectionPersister.values() ) { // final Type elementType = persister.getElementType(); -// if ( elementType.isEntityType() && ! elementType.isAnyType() ) { +// if ( elementType instanceof EntityType && ! elementType instanceof AnyType ) { // final Joinable joinable = ( (EntityType) elementType ).getAssociatedJoinable( factory ); // Collections.addAll( spaces, (String[]) ( (EntityPersister) joinable ).getQuerySpaces() ); // } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java index 46bcd2dc4b0b..779d0999983f 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java @@ -43,6 +43,7 @@ import org.hibernate.sql.results.spi.RowReader; import org.hibernate.sql.results.spi.RowTransformer; import org.hibernate.stat.spi.StatisticsImplementor; +import org.hibernate.type.EntityType; /** * @author Steve Ebersole @@ -268,7 +269,7 @@ private static void addCollectionToCache( ); boolean isPutFromLoad = true; - if ( collectionDescriptor.getElementType().isAssociationType() ) { + if ( collectionDescriptor.getElementType() instanceof EntityType ) { final EntityPersister entityPersister = ( (QueryableCollection) collectionDescriptor ).getElementPersister(); for ( Object id : entry.getState() ) { if ( persistenceContext.wasInsertedDuringTransaction( entityPersister, id ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java index c8272bcb17ea..ecd7de0a0f68 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -20,8 +20,12 @@ import org.hibernate.tuple.entity.EntityBasedBasicAttribute; import org.hibernate.tuple.entity.EntityBasedCompositionAttribute; import org.hibernate.tuple.entity.VersionProperty; +import org.hibernate.type.AnyType; import org.hibernate.type.AssociationType; +import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; +import org.hibernate.type.EntityType; import org.hibernate.type.Type; /** @@ -218,22 +222,19 @@ public static NonIdentifierAttribute buildEntityBasedAttribute( } private static NonIdentifierAttributeNature decode(Type type) { - if ( type.isAssociationType() ) { - - if ( type.isComponentType() ) { - // an any type is both an association and a composite... - return NonIdentifierAttributeNature.ANY; - } - - return type.isCollectionType() - ? NonIdentifierAttributeNature.COLLECTION - : NonIdentifierAttributeNature.ENTITY; + if ( type instanceof CollectionType ) { + return NonIdentifierAttributeNature.COLLECTION; + } + else if ( type instanceof EntityType ) { + return NonIdentifierAttributeNature.ENTITY; + } + else if ( type instanceof AnyType ) { + return NonIdentifierAttributeNature.ANY; + } + else if ( type instanceof ComponentType ) { + return NonIdentifierAttributeNature.COMPOSITE; } else { - if ( type.isComponentType() ) { - return NonIdentifierAttributeNature.COMPOSITE; - } - return NonIdentifierAttributeNature.BASIC; } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 106b6c090950..1312a0b142eb 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -552,7 +552,7 @@ public Set getSubclassEntityNames() { } private static boolean indicatesCollection(Type type) { - if ( type.isCollectionType() ) { + if ( type instanceof CollectionType ) { return true; } else if ( type.isComponentType() ) { @@ -567,7 +567,7 @@ else if ( type.isComponentType() ) { } private static boolean indicatesOwnedCollection(Type type, MetadataImplementor metadata) { - if ( type.isCollectionType() ) { + if ( type instanceof CollectionType ) { String role = ( (CollectionType) type ).getRole(); return !metadata.getCollectionBinding( role ).isInverse(); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java b/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java index 86da681a5136..cb7c5479ef3a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java @@ -476,7 +476,7 @@ public String getAssociatedEntityName(SessionFactoryImplementor factory) QueryableCollection collectionPersister = (QueryableCollection) factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( role ); - if ( !collectionPersister.getElementType().isEntityType() ) { + if ( !( collectionPersister.getElementType() instanceof EntityType ) ) { throw new MappingException( "collection was not an association: " + collectionPersister.getRole() diff --git a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java index 3305cfe6a01b..f896c33a549a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java @@ -491,7 +491,7 @@ else if ( isPersistentAttributeInterceptable( value ) ) { // we need to dig a little deeper, as that property might also be // an entity type, in which case we need to resolve its identifier final Type type = entityPersister.getPropertyType( uniqueKeyPropertyName ); - if ( type.isEntityType() ) { + if ( type instanceof EntityType ) { return ( (EntityType) type ).getIdentifier( propertyValue, session ); } @@ -515,7 +515,7 @@ else if ( value == null ) { // we need to dig a little deeper, as that property might also be // an entity type, in which case we need to resolve its identifier Type type = entityPersister.getPropertyType( uniqueKeyPropertyName ); - if ( type.isEntityType() ) { + if ( type instanceof EntityType ) { propertyValue = ( (EntityType) type ).getIdentifier( propertyValue, sessionFactory ); } @@ -639,7 +639,7 @@ public final Type getIdentifierOrUniqueKeyType(Mapping factory) throws MappingEx } else { Type type = factory.getReferencedPropertyType( getAssociatedEntityName(), uniqueKeyPropertyName ); - if ( type.isEntityType() ) { + if ( type instanceof EntityType ) { type = ( (EntityType) type ).getIdentifierOrUniqueKeyType( factory ); } return type; diff --git a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java index b043734a8ee4..e07a2ff8af10 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java @@ -192,7 +192,7 @@ public static Object[] replaceAssociations( } else { final Type type = types[i]; - if ( type.isComponentType() ) { + if ( type instanceof AnyType || type instanceof ComponentType ) { final CompositeType compositeType = (CompositeType) type; // need to extract the component values and check for subtype replacements... final Type[] subtypes = compositeType.getSubtypes(); @@ -226,11 +226,11 @@ public static Object[] replaceAssociations( } copied[i] = target[i]; } - else if ( !type.isAssociationType() ) { - copied[i] = target[i]; + else if ( type instanceof CollectionType || type instanceof EntityType ) { + copied[i] = types[i].replace( currentOriginal, target[i], session, owner, copyCache, foreignKeyDirection ); } else { - copied[i] = types[i].replace( currentOriginal, target[i], session, owner, copyCache, foreignKeyDirection ); + copied[i] = target[i]; } } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java index d84bb582334d..d3ede1e2fae8 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java @@ -200,7 +200,7 @@ private boolean isCollectionElementSame( // Currently the tuple is { owner_id, entity_id, rev } and so having this special // treatment is critical to avoid HHH-13080. // - if ( elementType.isEntityType() && !revisionTypeInId ) { + if ( elementType instanceof EntityType && !revisionTypeInId ) { // This is a short-circuit to check for reference equality only. // There is no need to delegate to the identifier if the objects are reference equal. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java index ab289d8f83f6..6cfe0f5bb212 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java @@ -432,7 +432,7 @@ private boolean isNonIdentifierWhereConditionsRequired(String entityName, String final Type propertyType = session.getSessionFactory() .getMappingMetamodel() .getEntityDescriptor( entityName ).getPropertyType( propertyName ); - if ( propertyType.isCollectionType() ) { + if ( propertyType instanceof CollectionType ) { final CollectionType collectionType = (CollectionType) propertyType; final Type collectionElementType = collectionType.getElementType( session.getSessionFactory() ); if ( collectionElementType instanceof ComponentType ) { From 6a01a1212a72551acb3a2f16f42369d1ee744629 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Tue, 20 Aug 2024 14:37:00 +0200 Subject: [PATCH 2/2] HHH-18506 Reduce itable stubs during dirty checking --- .../entity/AbstractEntityPersister.java | 2 +- .../persister/entity/DirtyHelper.java | 64 +++++++++++++++++++ .../tuple/entity/EntityMetamodel.java | 12 ++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index a6e2686e6c56..ef8c6bcd09b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -3696,7 +3696,7 @@ public boolean isSubclassPropertyNullable(int i) { public int[] findDirty(Object[] currentState, Object[] previousState, Object entity, SharedSessionContractImplementor session) throws HibernateException { int[] props = DirtyHelper.findDirty( - entityMetamodel.getProperties(), + entityMetamodel.getDirtyCheckablePropertyTypes(), currentState, previousState, propertyColumnUpdateable, diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java index 289677fcf241..124a16185199 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java @@ -11,6 +11,14 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.tuple.NonIdentifierAttribute; +import org.hibernate.type.AnyType; +import org.hibernate.type.BasicType; +import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; +import org.hibernate.type.ManyToOneType; +import org.hibernate.type.Type; + +import org.checkerframework.checker.nullness.qual.Nullable; /** * Operations for searching an array of property values for modified elements. @@ -72,6 +80,62 @@ else if ( previousState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { } } + /** + * Determine if any of the given field values are dirty, returning an array containing + * indices of the dirty fields. + *

+ * If it is determined that no fields are dirty, null is returned. + * + * @param propertyTypes The property types that are dirty checkable. null entry for non-dirty checkable properties + * @param currentState The current state of the entity + * @param previousState The baseline state of the entity + * @param includeColumns Columns to be included in the dirty checking, per property + * @param session The session from which the dirty check request originated. + * + * @return Array containing indices of the dirty properties, or null if no properties considered dirty. + */ + public static int[] findDirty( + @Nullable Type[] propertyTypes, + final Object[] currentState, + final Object[] previousState, + final boolean[][] includeColumns, + final SharedSessionContractImplementor session) { + int[] results = null; + int count = 0; + int span = propertyTypes.length; + + for ( int i = 0; i < span; i++ ) { + + if ( isDirty( propertyTypes, currentState, previousState, includeColumns, session, i ) ) { + if ( results == null ) { + results = new int[span]; + } + results[count++] = i; + } + } + + return count == 0 ? null : ArrayHelper.trim( results, count ); + } + + private static boolean isDirty( + @Nullable Type[] propertyTypes, + Object[] currentState, + Object[] previousState, + boolean[][] includeColumns, + SharedSessionContractImplementor session, int i) { + final Type propertyType; + if ( currentState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY + || ( propertyType = propertyTypes[i] ) == null ) { + return false; + } + else if ( previousState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { + return true; + } + else { + return propertyType.isDirty( previousState[i], currentState[i], includeColumns[i], session ); + } + } + /** * Determine if any of the given field values are modified, returning an array containing * indices of the modified fields. diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 1312a0b142eb..b59c2caa9cd2 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -52,8 +52,11 @@ import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.ManyToOneType; +import org.hibernate.type.OneToOneType; import org.hibernate.type.Type; +import org.checkerframework.checker.nullness.qual.Nullable; + import static java.util.Collections.singleton; import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.util.ReflectHelper.isAbstractClass; @@ -92,6 +95,7 @@ public class EntityMetamodel implements Serializable { // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private final String[] propertyNames; private final Type[] propertyTypes; + private final @Nullable Type[] dirtyCheckablePropertyTypes; private final boolean[] propertyLaziness; private final boolean[] propertyUpdateability; private final boolean[] nonlazyPropertyUpdateability; @@ -210,6 +214,7 @@ public EntityMetamodel( // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ propertyNames = new String[propertySpan]; propertyTypes = new Type[propertySpan]; + dirtyCheckablePropertyTypes = new Type[propertySpan]; propertyUpdateability = new boolean[propertySpan]; propertyInsertability = new boolean[propertySpan]; nonlazyPropertyUpdateability = new boolean[propertySpan]; @@ -298,6 +303,9 @@ public EntityMetamodel( propertyNames[i] = attribute.getName(); final Type propertyType = attribute.getType(); propertyTypes[i] = propertyType; + if ( attribute.isDirtyCheckable() && !( propertyType instanceof OneToOneType ) ) { + dirtyCheckablePropertyTypes[i] = propertyType; + } propertyNullability[i] = attribute.isNullable(); propertyUpdateability[i] = attribute.isUpdateable(); propertyInsertability[i] = attribute.isInsertable(); @@ -757,6 +765,10 @@ public Type[] getPropertyTypes() { return propertyTypes; } + public @Nullable Type[] getDirtyCheckablePropertyTypes() { + return dirtyCheckablePropertyTypes; + } + public boolean[] getPropertyLaziness() { return propertyLaziness; }