diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java index b78a40a87e94..fb5bb95bee88 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java @@ -283,9 +283,9 @@ private void handleGeneratedProperties(EntityEntry entry, GeneratedValues genera */ protected void handleDeleted(EntityEntry entry) { if ( entry.getStatus() == Status.DELETED ) { - final var entityMetamodel = getPersister().getEntityMetamodel(); + final var entityMetamodel = getPersister(); final boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() - && entityMetamodel.getOptimisticLockStyle().isAllOrDirty(); + && entityMetamodel.optimisticLockStyle().isAllOrDirty(); if ( isImpliedOptimisticLocking && entry.getLoadedState() != null ) { // The entity will be deleted, and because we are going to create a delete statement // that uses all the state values in the where clause, the entry state needs to be 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 23b1030963d9..dddf6ec4d65d 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 @@ -355,8 +355,8 @@ public EntityRelatedState(EntityPersister persister, // versioned, we need to fetch the current version. this.initializeBeforeWrite = !inLineDirtyChecking - || !persister.getEntityMetamodel().isDynamicUpdate() - || persister.isVersioned(); + || !persister.isDynamicUpdate() + || persister.isVersioned(); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeEnhancementMetadataPojoImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeEnhancementMetadataPojoImpl.java index c4926385fba7..e57cbfc310c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeEnhancementMetadataPojoImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeEnhancementMetadataPojoImpl.java @@ -187,8 +187,7 @@ public PersistentAttributeInterceptable createEnhancedProxy(EntityKey entityKey, } // inject the interceptor - persister.getEntityMetamodel() - .getBytecodeEnhancementMetadata() + persister.getBytecodeEnhancementMetadata() .injectEnhancedEntityAsProxyInterceptor( entity, entityKey, session ); return entity; 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 a06647b2ba1f..6d6025bf86d3 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 @@ -665,7 +665,7 @@ private static boolean cascadeDeleteEnabled(CascadingAction action, Colle private static boolean cascadeDeleteEnabled(CascadingAction action, EntityPersister persister, int i) { return action.directionAffectedByCascadeDelete() == ForeignKeyDirection.TO_PARENT - && persister.getEntityMetamodel().getPropertyOnDeleteActions()[i] == OnDeleteAction.CASCADE; + && persister.getPropertyOnDeleteActions()[i] == OnDeleteAction.CASCADE; } private static boolean cascadeDeleteEnabled(CascadingAction action, CompositeType componentType, int i) { diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryImpl.java index 8139f50b697f..1cb39fee8178 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryImpl.java @@ -287,7 +287,7 @@ public void postUpdate(Object entity, Object[] updatedState, Object nextVersion) if ( persister.isVersioned() ) { version = nextVersion; - persister.setValue( entity, persister.getVersionProperty(), nextVersion ); + persister.setValue( entity, persister.getVersionPropertyIndex(), nextVersion ); } processIfSelfDirtinessTracker( entity, EntityEntryImpl::clearDirtyAttributes ); @@ -421,7 +421,7 @@ public boolean isModifiableEntity() { @Override public void forceLocked(Object entity, Object nextVersion) { version = nextVersion; - final int versionProperty = persister.getVersionProperty(); + final int versionProperty = persister.getVersionPropertyIndex(); loadedState[versionProperty] = version; setLockMode( PESSIMISTIC_FORCE_INCREMENT ); persister.setValue( entity, versionProperty, nextVersion ); 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 5700d4a11efa..6752126b3758 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 @@ -105,7 +105,7 @@ public void checkNullability(final Object[] values, final EntityPersister persis final boolean[] nullability = persister.getPropertyNullability(); final boolean[] checkability = getCheckability( persister ); final Type[] propertyTypes = persister.getPropertyTypes(); - final Generator[] generators = persister.getEntityMetamodel().getGenerators(); + final Generator[] generators = persister.getGenerators(); for ( int i = 0; i < values.length; i++ ) { if ( checkability[i] && !unfetched( values[i] ) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java index dd13a5da36f5..9e01c3ff6c78 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java @@ -348,7 +348,7 @@ public Object getNaturalIdSnapshot(Object id, EntityPersister persister) throws return cachedValue; } // check to see if the natural id is mutable/immutable - else if ( persister.getEntityMetamodel().hasImmutableNaturalId() ) { + else if ( persister.hasImmutableNaturalId() ) { // an immutable natural-id is not retrieved during a normal database-snapshot operation... final Object naturalIdFromDb = persister.getNaturalIdentifierSnapshot( id, session ); naturalIdResolutions.cacheResolutionFromLoad( id, naturalIdFromDb, persister ); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/Versioning.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/Versioning.java index a2df375a98d4..bebda63bcfa7 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/Versioning.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/Versioning.java @@ -67,7 +67,7 @@ public static boolean seedVersion( Object[] fields, EntityPersister persister, SharedSessionContractImplementor session) { - final int versionProperty = persister.getVersionProperty(); + final int versionProperty = persister.getVersionPropertyIndex(); final Object initialVersion = fields[versionProperty]; if ( isNullInitialVersion( initialVersion ) ) { fields[versionProperty] = persister.getVersionGenerator().generate( session, entity, initialVersion, INSERT ); @@ -150,7 +150,7 @@ public static Object increment(Object version, EntityVersionMapping versionMappi */ public static void setVersion(Object[] fields, Object version, EntityPersister persister) { if ( persister.isVersioned() ) { - fields[ persister.getVersionProperty() ] = version; + fields[ persister.getVersionPropertyIndex() ] = version; } } @@ -162,7 +162,7 @@ public static void setVersion(Object[] fields, Object version, EntityPersister p * @return The extracted optimistic locking value */ public static Object getVersion(Object[] fields, EntityPersister persister) { - return persister.isVersioned() ? fields[persister.getVersionProperty()] : null; + return persister.isVersioned() ? fields[persister.getVersionPropertyIndex()] : null; } /** diff --git a/hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java b/hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java index 53f4f37074ff..b976681be8ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java @@ -298,7 +298,7 @@ else if ( supportsReturning( dialect, timing ) && noCustomSql( persister, timing } else if ( timing == EventType.INSERT && persister.getNaturalIdentifierProperties() != null - && !persister.getEntityMetamodel().isNaturalIdentifierInsertGenerated() ) { + && !persister.isNaturalIdentifierInsertGenerated() ) { return new UniqueKeySelectingDelegate( persister, getNaturalIdPropertyNames( persister ), timing ); } return null; diff --git a/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java index b6bfb1d519ab..ecd911189ee7 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java @@ -74,7 +74,7 @@ else if ( sessionFactoryOptions.isGetGeneratedKeysEnabled() ) { return dialect.getIdentityColumnSupport().buildGetGeneratedKeysDelegate( persister ); } else if ( persister.getNaturalIdentifierProperties() != null - && !persister.getEntityMetamodel().isNaturalIdentifierInsertGenerated() ) { + && !persister.isNaturalIdentifierInsertGenerated() ) { return new UniqueKeySelectingDelegate( persister, getNaturalIdPropertyNames( persister ), INSERT ); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/internal/NaturalIdHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/NaturalIdHelper.java index 7c1146baec17..382fdce5508c 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/NaturalIdHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/NaturalIdHelper.java @@ -23,7 +23,7 @@ public static String[] getNaturalIdPropertyNames(EntityPersister persister) { throw new IdentifierGenerationException( "Entity '" + persister.getEntityName() + "' has no '@NaturalId' property" ); } - if ( persister.getEntityMetamodel().isNaturalIdentifierInsertGenerated() ) { + if ( persister.isNaturalIdentifierInsertGenerated() ) { throw new IdentifierGenerationException( "Entity '" + persister.getEntityName() + "' has a '@NaturalId' property which is also defined as insert-generated" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java index 5913fe0dbef2..3faef763f214 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java @@ -519,7 +519,7 @@ protected Object versionToUpsert(Object entity, EntityPersister persister, Objec } // this is a nonsense but avoids setting version restriction // parameter to null later on deep in the guts - return state[persister.getVersionProperty()]; + return state[persister.getVersionPropertyIndex()]; } else { final Object newVersion = incrementVersion( entity, oldVersion, persister, this ); @@ -1013,8 +1013,7 @@ public Object internalLoad( // first, check to see if we can use "bytecode proxies" - final var entityMetamodel = persister.getEntityMetamodel(); - final var enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata(); + final var enhancementMetadata = persister.getBytecodeEnhancementMetadata(); if ( enhancementMetadata.isEnhancedForLazyLoading() ) { // if the entity defines a HibernateProxy factory, see if there is an // existing proxy associated with the PC - and if so, use it @@ -1031,14 +1030,14 @@ public Object internalLoad( } // specialized handling for entities with subclasses with a HibernateProxy factory - if ( entityMetamodel.hasSubclasses() ) { + if ( persister.hasSubclasses() ) { // entities with subclasses that define a ProxyFactory can create a HibernateProxy. LOG.trace( "Creating a HibernateProxy for to-one association with subclasses to honor laziness" ); return createProxy( entityKey ); } return enhancementMetadata.createEnhancedProxy( entityKey, false, this ); } - else if ( !entityMetamodel.hasSubclasses() ) { + else if ( !persister.hasSubclasses() ) { return enhancementMetadata.createEnhancedProxy( entityKey, false, this ); } // If we get here, then the entity class has subclasses and there is no HibernateProxy factory. diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/IdentifierLoadAccessImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/IdentifierLoadAccessImpl.java index 980912f266fc..ac5d475e1f6f 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/IdentifierLoadAccessImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/IdentifierLoadAccessImpl.java @@ -208,8 +208,7 @@ private void initializeIfNecessary(Object result) { } } else { - final var enhancementMetadata = - entityPersister.getEntityMetamodel().getBytecodeEnhancementMetadata(); + final var enhancementMetadata = entityPersister.getBytecodeEnhancementMetadata(); if ( enhancementMetadata.isEnhancedForLazyLoading() && enhancementMetadata.extractLazyInterceptor( result ) instanceof EnhancementAsProxyLazinessInterceptor lazinessInterceptor ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java index ed33ffb83280..a5efe315377b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java @@ -8,7 +8,7 @@ import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor; import org.hibernate.mapping.PersistentClass; import org.hibernate.metamodel.spi.EntityInstantiator; -import org.hibernate.tuple.entity.EntityMetamodel; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.descriptor.java.JavaType; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; @@ -20,31 +20,30 @@ * @author Steve Ebersole */ public abstract class AbstractEntityInstantiatorPojo extends AbstractPojoInstantiator implements EntityInstantiator { - private final EntityMetamodel entityMetamodel; + private final Class proxyInterface; private final boolean applyBytecodeInterception; private final LazyAttributeLoadingInterceptor.EntityRelatedState loadingInterceptorState; public AbstractEntityInstantiatorPojo( - EntityMetamodel entityMetamodel, + EntityPersister persister, PersistentClass persistentClass, JavaType javaType) { super( javaType.getJavaTypeClass() ); - this.entityMetamodel = entityMetamodel; - this.proxyInterface = persistentClass.getProxyInterface(); + proxyInterface = persistentClass.getProxyInterface(); //TODO this PojoEntityInstantiator appears to not be reused ?! - this.applyBytecodeInterception = + applyBytecodeInterception = isPersistentAttributeInterceptableType( persistentClass.getMappedClass() ); if ( applyBytecodeInterception ) { - this.loadingInterceptorState = new LazyAttributeLoadingInterceptor.EntityRelatedState( - entityMetamodel.getName(), - entityMetamodel.getBytecodeEnhancementMetadata() + loadingInterceptorState = new LazyAttributeLoadingInterceptor.EntityRelatedState( + persister.getEntityName(), + persister.getBytecodeEnhancementMetadata() .getLazyAttributesMetadata() .getLazyAttributeNames() ); } else { - this.loadingInterceptorState = null; + loadingInterceptorState = null; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java index be84fe865730..3ac9468d0d0b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java @@ -6,7 +6,7 @@ import org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimizer; import org.hibernate.mapping.PersistentClass; -import org.hibernate.tuple.entity.EntityMetamodel; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.descriptor.java.JavaType; /** @@ -19,11 +19,11 @@ public class EntityInstantiatorPojoOptimized extends AbstractEntityInstantiatorP private final InstantiationOptimizer instantiationOptimizer; public EntityInstantiatorPojoOptimized( - EntityMetamodel entityMetamodel, + EntityPersister persister, PersistentClass persistentClass, JavaType javaType, InstantiationOptimizer instantiationOptimizer) { - super( entityMetamodel, persistentClass, javaType ); + super( persister, persistentClass, javaType ); this.instantiationOptimizer = instantiationOptimizer; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java index 2aacce91bd95..57642d938da7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java @@ -12,7 +12,7 @@ import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.mapping.PersistentClass; -import org.hibernate.tuple.entity.EntityMetamodel; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.descriptor.java.JavaType; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; @@ -31,23 +31,23 @@ public class EntityInstantiatorPojoStandard extends AbstractEntityInstantiatorPo private final Constructor constructor; public EntityInstantiatorPojoStandard( - EntityMetamodel entityMetamodel, + EntityPersister persister, PersistentClass persistentClass, JavaType javaType) { - super( entityMetamodel, persistentClass, javaType ); + super( persister, persistentClass, javaType ); proxyInterface = persistentClass.getProxyInterface(); constructor = isAbstract() ? null : resolveConstructor( getMappedPojoClass() ); applyBytecodeInterception = isPersistentAttributeInterceptableType( persistentClass.getMappedClass() ); if ( applyBytecodeInterception ) { - this.loadingInterceptorState = new LazyAttributeLoadingInterceptor.EntityRelatedState( - entityMetamodel.getName(), - entityMetamodel.getBytecodeEnhancementMetadata() + loadingInterceptorState = new LazyAttributeLoadingInterceptor.EntityRelatedState( + persister.getEntityName(), + persister.getBytecodeEnhancementMetadata() .getLazyAttributesMetadata() .getLazyAttributeNames() ); } else { - this.loadingInterceptorState = null; + loadingInterceptorState = null; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java index 0284d4137c5e..29cab619027d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java @@ -122,7 +122,7 @@ public EntityRepresentationStrategyPojoStandard( propertyAccessMap = buildPropertyAccessMap( bootDescriptor ); reflectionOptimizer = resolveReflectionOptimizer( bytecodeProvider ); - instantiator = determineInstantiator( bootDescriptor, runtimeDescriptor.getEntityMetamodel() ); + instantiator = determineInstantiator( bootDescriptor, runtimeDescriptor ); } private ProxyFactory resolveProxyFactory( @@ -141,11 +141,10 @@ private ProxyFactory resolveProxyFactory( return null; } else { - final var entityMetamodel = entityPersister.getEntityMetamodel(); - if ( proxyJavaType != null && entityMetamodel.isLazy() ) { + if ( proxyJavaType != null && entityPersister.isLazy() ) { final var proxyFactory = createProxyFactory( bootDescriptor, bytecodeProvider, creationContext ); if ( proxyFactory == null ) { - entityMetamodel.setLazy( false ); + ((EntityMetamodel) entityPersister).setLazy( false ); } return proxyFactory; } @@ -163,17 +162,17 @@ private Map buildPropertyAccessMap(PersistentClass bootD return propertyAccessMap; } - private EntityInstantiator determineInstantiator(PersistentClass bootDescriptor, EntityMetamodel entityMetamodel) { + private EntityInstantiator determineInstantiator(PersistentClass bootDescriptor, EntityPersister persister) { if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) { return new EntityInstantiatorPojoOptimized( - entityMetamodel, + persister, bootDescriptor, mappedJtd, reflectionOptimizer.getInstantiationOptimizer() ); } else { - return new EntityInstantiatorPojoStandard( entityMetamodel, bootDescriptor, mappedJtd ); + return new EntityInstantiatorPojoStandard( persister, bootDescriptor, mappedJtd ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java index 85182ff277cd..a5b8be4ab175 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java @@ -148,14 +148,14 @@ default int getJdbcTypeCount() { * Whether this entity is defined as abstract using the Java {@code abstract} keyword */ default boolean isAbstract() { - return getEntityPersister().getEntityMetamodel().isAbstract(); + return getEntityPersister().isAbstract(); } /** * Whether this entity mapping has any subtype mappings */ default boolean hasSubclasses() { - return getEntityPersister().getEntityMetamodel().hasSubclasses(); + return getEntityPersister().hasSubclasses(); } /** @@ -221,11 +221,11 @@ default boolean isTypeOrSuperType(ManagedMappingType targetType) { * inheritance hierarchy */ default int getSubclassId() { - return getEntityPersister().getEntityMetamodel().getSubclassId(); + return getEntityPersister().getSubclassId(); } default Set getSubclassEntityNames() { - return getEntityPersister().getEntityMetamodel().getSubclassEntityNames(); + return getEntityPersister().getSubclassEntityNames(); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractSingularAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractSingularAttributeMapping.java index ad017a463df2..29a42f6b892b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractSingularAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractSingularAttributeMapping.java @@ -52,7 +52,7 @@ protected AbstractSingularAttributeMapping( AbstractSingularAttributeMapping ori @Override public Generator getGenerator() { - return findContainingEntityMapping().getEntityPersister().getEntityMetamodel().getGenerators()[getStateArrayPosition()]; + return findContainingEntityMapping().getEntityPersister().getGenerators()[getStateArrayPosition()]; } } 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 e27f0fc4e832..81210afce5de 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 @@ -122,12 +122,12 @@ private static boolean isSubsequentSelectDelayed(AssociationType type, SessionFa return false; } else if ( type instanceof EntityType ) { - final EntityPersister entityPersister = (EntityPersister) type.getAssociatedJoinable( sessionFactory ); - return entityPersister.getEntityMetamodel().isLazy(); + final var entityPersister = (EntityPersister) type.getAssociatedJoinable( sessionFactory ); + return entityPersister.isLazy(); } else { - final CollectionPersister cp = ( (CollectionPersister) type.getAssociatedJoinable( sessionFactory ) ); - return cp.isLazy() || cp.isExtraLazy(); + final var collectionPersister = (CollectionPersister) type.getAssociatedJoinable( sessionFactory ); + return collectionPersister.isLazy() || collectionPersister.isExtraLazy(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/GeneratedValuesProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/GeneratedValuesProcessor.java index f91293407b23..beb8e5b42279 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/GeneratedValuesProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/GeneratedValuesProcessor.java @@ -123,7 +123,7 @@ private int numberOfGeneratedNonIdentifierProperties(EventType timing) { public static List getGeneratedAttributes(EntityMappingType entityDescriptor, EventType timing) { // todo (6.0): For now, we rely on the entity metamodel as composite attributes report // GenerationTiming.NEVER even if they have attributes that would need generation - final Generator[] generators = entityDescriptor.getEntityPersister().getEntityMetamodel().getGenerators(); + final Generator[] generators = entityDescriptor.getEntityPersister().getGenerators(); final List generatedValuesToSelect = new ArrayList<>(); entityDescriptor.forEachAttributeMapping( mapping -> { final Generator generator = generators[ mapping.getStateArrayPosition() ]; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java index d05bc5a22aad..27bf81ce462e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java @@ -14,11 +14,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.generator.Generator; import org.hibernate.mapping.GeneratorSettings; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.service.ServiceRegistry; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; import org.hibernate.type.spi.TypeConfiguration; @@ -68,11 +65,4 @@ default MetadataImplementor getMetadata() { Map getGenerators(); GeneratorSettings getGeneratorSettings(); - - /* - * Used by Hibernate Reactive - */ - default EntityMetamodel createEntityMetamodel(PersistentClass persistentClass, EntityPersister persister) { - return new EntityMetamodel( persistentClass, persister, this ); - } } 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 7482ca6ad683..bfdcd4e7fbee 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 @@ -27,11 +27,9 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.mutation.ParameterUsage; import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions; -import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.profile.internal.FetchProfileAffectee; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SubselectFetch; @@ -55,18 +53,12 @@ import org.hibernate.mapping.Formula; import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.IndexedCollection; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Selectable; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.CollectionPart; -import org.hibernate.metamodel.mapping.DiscriminatorMapping; -import org.hibernate.metamodel.mapping.DiscriminatorValueDetails; -import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; -import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ManagedMappingType; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping; @@ -92,24 +84,20 @@ import org.hibernate.sql.Alias; import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.Template; +import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl; import org.hibernate.sql.ast.spi.SqlAliasBaseConstant; import org.hibernate.sql.ast.spi.SqlAliasBaseManager; import org.hibernate.sql.ast.spi.SqlAstCreationState; -import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.AliasedExpression; -import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.ast.tree.select.QuerySpec; -import org.hibernate.sql.ast.tree.select.SelectClause; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.TableMapping; import org.hibernate.sql.model.TableMapping.MutationDetails; import org.hibernate.sql.model.ast.ColumnValueBinding; -import org.hibernate.sql.model.ast.ColumnValueParameter; import org.hibernate.sql.model.ast.ColumnValueParameterList; import org.hibernate.sql.model.ast.ColumnWriteFragment; import org.hibernate.sql.model.ast.MutatingTableReference; @@ -125,15 +113,13 @@ import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.type.spi.TypeConfiguration; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -258,41 +244,36 @@ public abstract class AbstractCollectionPersister public AbstractCollectionPersister( Collection collectionBootDescriptor, @Nullable CollectionDataAccess cacheAccessStrategy, - RuntimeModelCreationContext creationContext) throws MappingException, CacheException { + RuntimeModelCreationContext creationContext) + throws MappingException, CacheException { + factory = creationContext.getSessionFactory(); + this.collectionBootDescriptor = collectionBootDescriptor; + this.collectionSemantics = + creationContext.getBootstrapContext().getMetadataBuildingOptions() + .getPersistentCollectionRepresentationResolver() + .resolveRepresentation( collectionBootDescriptor ); - this.factory = creationContext.getSessionFactory(); - this.collectionSemantics = creationContext.getBootstrapContext() - .getMetadataBuildingOptions() - .getPersistentCollectionRepresentationResolver() - .resolveRepresentation( collectionBootDescriptor ); this.cacheAccessStrategy = cacheAccessStrategy; - if ( creationContext.getSessionFactoryOptions().isStructuredCacheEntriesEnabled() ) { - cacheEntryStructure = collectionBootDescriptor.isMap() - ? StructuredMapCacheEntry.INSTANCE - : StructuredCollectionCacheEntry.INSTANCE; - } - else { - cacheEntryStructure = UnstructuredCacheEntry.INSTANCE; - } - useShallowQueryCacheLayout = shouldUseShallowCacheLayout( - collectionBootDescriptor.getQueryCacheLayout(), - creationContext.getSessionFactoryOptions() - ); + cacheEntryStructure = cacheEntryStructure( collectionBootDescriptor, creationContext ); + useShallowQueryCacheLayout = + shouldUseShallowCacheLayout( collectionBootDescriptor.getQueryCacheLayout(), + creationContext.getSessionFactoryOptions() ); dialect = creationContext.getDialect(); sqlExceptionHelper = creationContext.getJdbcServices().getSqlExceptionHelper(); collectionType = collectionBootDescriptor.getCollectionType(); navigableRole = new NavigableRole( collectionBootDescriptor.getRole() ); - ownerPersister = creationContext.getDomainModel() - .getEntityDescriptor( collectionBootDescriptor.getOwnerEntityName() ); + ownerPersister = + creationContext.getDomainModel() + .getEntityDescriptor( collectionBootDescriptor.getOwnerEntityName() ); queryLoaderName = collectionBootDescriptor.getLoaderName(); isMutable = collectionBootDescriptor.isMutable(); mappedByProperty = collectionBootDescriptor.getMappedByProperty(); - final Value elementBootDescriptor = collectionBootDescriptor.getElement(); - final Table table = collectionBootDescriptor.getCollectionTable(); + final var elementBootDescriptor = collectionBootDescriptor.getElement(); + final var table = collectionBootDescriptor.getCollectionTable(); elementType = elementBootDescriptor.getType(); // isSet = collectionBinding.isSet(); @@ -311,20 +292,20 @@ public AbstractCollectionPersister( hasOrphanDelete = collectionBootDescriptor.hasOrphanDelete(); - batchSize = collectionBootDescriptor.getBatchSize() < 0 - ? factory.getSessionFactoryOptions().getDefaultBatchFetchSize() - : collectionBootDescriptor.getBatchSize(); + batchSize = batchSize( collectionBootDescriptor, creationContext ); isVersioned = collectionBootDescriptor.isOptimisticLocked(); // KEY - keyType = collectionBootDescriptor.getKey().getType(); - final int keySpan = collectionBootDescriptor.getKey().getColumnSpan(); + final var key = collectionBootDescriptor.getKey(); + + keyType = key.getType(); + final int keySpan = key.getColumnSpan(); keyColumnNames = new String[keySpan]; keyColumnAliases = new String[keySpan]; int k = 0; - for ( Selectable selectable: collectionBootDescriptor.getKey().getSelectables() ) { + for ( var selectable: key.getSelectables() ) { // NativeSQL: collect key column and auto-aliases keyColumnAliases[k] = selectable.getAlias( dialect, table ); if ( selectable instanceof Column column ) { @@ -349,10 +330,10 @@ public AbstractCollectionPersister( elementPersister = null; } // Defer this after the element persister was determined, - // because it is needed in OneToManyPersister.getTableName() + // because it's needed in OneToManyPersister.getTableName() spaces[0] = getTableName(); - final TypeConfiguration typeConfiguration = creationContext.getTypeConfiguration(); + final var typeConfiguration = creationContext.getTypeConfiguration(); final int elementSpan = elementBootDescriptor.getColumnSpan(); elementColumnAliases = new String[elementSpan]; @@ -366,28 +347,23 @@ public AbstractCollectionPersister( elementColumnIsGettable = new boolean[elementSpan]; boolean isPureFormula = true; final boolean oneToMany = collectionBootDescriptor.isOneToMany(); - boolean[] columnInsertability = null; - if ( !oneToMany ) { - columnInsertability = elementBootDescriptor.getColumnInsertability(); - } + final boolean[] columnInsertability = oneToMany ? null : elementBootDescriptor.getColumnInsertability(); int j = 0; - for ( Selectable selectable: elementBootDescriptor.getSelectables() ) { + for ( var selectable: elementBootDescriptor.getSelectables() ) { elementColumnAliases[j] = selectable.getAlias( dialect, table ); - if ( selectable.isFormula() ) { - Formula form = (Formula) selectable; - elementFormulaTemplates[j] = form.getTemplate( dialect, typeConfiguration ); - elementFormulas[j] = form.getFormula(); + if ( selectable instanceof Formula formula ) { + elementFormulaTemplates[j] = formula.getTemplate( dialect, typeConfiguration ); + elementFormulas[j] = formula.getFormula(); } - else { - final Column col = (Column) selectable; - elementColumnNames[j] = col.getQuotedName( dialect ); - elementColumnWriters[j] = col.getWriteExpr( + else if ( selectable instanceof Column column ) { + elementColumnNames[j] = column.getQuotedName( dialect ); + elementColumnWriters[j] = column.getWriteExpr( elementBootDescriptor.getSelectableType( factory.getRuntimeMetamodels(), j ), dialect, creationContext.getBootModel() ); - elementColumnReaders[j] = col.getReadExpr( dialect ); - elementColumnReaderTemplates[j] = col.getTemplate( dialect, typeConfiguration ); + elementColumnReaders[j] = column.getReadExpr( dialect ); + elementColumnReaderTemplates[j] = column.getTemplate( dialect, typeConfiguration ); elementColumnIsGettable[j] = true; if ( elementType instanceof ComponentType || elementType instanceof AnyType ) { // Implements desired behavior specifically for @ElementCollection mappings. @@ -421,15 +397,14 @@ public AbstractCollectionPersister( indexColumnAliases = new String[indexSpan]; int i = 0; boolean hasFormula = false; - for ( Selectable selectable: index.getSelectables() ) { + for ( var selectable: index.getSelectables() ) { indexColumnAliases[i] = selectable.getAlias( dialect ); - if ( selectable.isFormula() ) { - final Formula indexForm = (Formula) selectable; - indexFormulaTemplates[i] = indexForm.getTemplate( dialect, typeConfiguration ); - indexFormulas[i] = indexForm.getFormula(); + if ( selectable instanceof Formula indexFormula ) { + indexFormulaTemplates[i] = indexFormula.getTemplate( dialect, typeConfiguration ); + indexFormulas[i] = indexFormula.getFormula(); hasFormula = true; } - else { + else if ( selectable instanceof Column indexColumn ) { if ( indexedCollection.hasMapKeyProperty() ) { // If the Map key is set via @MapKey, it should not be written // since it is a reference to a field of the associated entity. @@ -439,8 +414,7 @@ public AbstractCollectionPersister( indexColumnUpdatability[i] = false; hasFormula = true; // this is incorrect, but needed for some reason } - final Column indexCol = (Column) selectable; - indexColumnNames[i] = indexCol.getQuotedName( dialect ); + indexColumnNames[i] = indexColumn.getQuotedName( dialect ); indexColumnIsGettable[i] = true; indexColumnIsSettable[i] = indexColumnInsertability[i] || indexColumnUpdatability[i]; } @@ -465,12 +439,12 @@ public AbstractCollectionPersister( throw new MappingException( "one-to-many collections with identifiers are not supported" ); } //noinspection ConstantConditions - final IdentifierCollection idColl = (IdentifierCollection) collectionBootDescriptor; - identifierType = idColl.getIdentifier().getType(); - final Column col = idColl.getIdentifier().getColumns().get(0); - identifierColumnName = col.getQuotedName( dialect ); - identifierColumnAlias = col.getAlias( dialect ); - identifierGenerator = createGenerator( creationContext, idColl ); + final var idCollection = (IdentifierCollection) collectionBootDescriptor; + identifierType = idCollection.getIdentifier().getType(); + final var idColumn = idCollection.getIdentifier().getColumns().get(0); + identifierColumnName = idColumn.getQuotedName( dialect ); + identifierColumnAlias = idColumn.getAlias( dialect ); + identifierGenerator = createGenerator( creationContext, idCollection ); } else { identifierType = null; @@ -484,7 +458,7 @@ public AbstractCollectionPersister( isInverse = collectionBootDescriptor.isInverse(); - keyIsUpdateable = collectionBootDescriptor.getKey().isUpdateable(); + keyIsUpdateable = key.isUpdateable(); elementClass = collectionBootDescriptor instanceof Array arrayDescriptor @@ -496,33 +470,17 @@ public AbstractCollectionPersister( hasManyToManyOrder = collectionBootDescriptor.getManyToManyOrdering() != null; // Handle any filters applied to this collectionBinding - if ( collectionBootDescriptor.getFilters().isEmpty() ) { - filterHelper = null; - } - else { - final Map entityNameByTableNameMap; - if ( elementPersister == null ) { - entityNameByTableNameMap = null; - } - else { - entityNameByTableNameMap = AbstractEntityPersister.getEntityNameByTableNameMap( - creationContext.getBootModel().getEntityBinding( elementPersister.getEntityName() ), - factory.getSqlStringGenerationContext() - ); - } - filterHelper = new FilterHelper( collectionBootDescriptor.getFilters(), entityNameByTableNameMap, factory ); - } - + filterHelper = filterHelper( collectionBootDescriptor, elementPersister, creationContext ); // Handle any filters applied to this collectionBinding for many-to-many - manyToManyFilterHelper = collectionBootDescriptor.getManyToManyFilters().isEmpty() ? null - : new FilterHelper( collectionBootDescriptor.getManyToManyFilters(), factory ); + manyToManyFilterHelper = manyToManyFilterHelper( collectionBootDescriptor, creationContext ); - if ( isEmpty( collectionBootDescriptor.getManyToManyWhere() ) ) { + final String manyToManyWhere = collectionBootDescriptor.getManyToManyWhere(); + if ( isEmpty( manyToManyWhere ) ) { manyToManyWhereString = null; manyToManyWhereTemplate = null; } else { - manyToManyWhereString = "( " + collectionBootDescriptor.getManyToManyWhere() + ")"; + manyToManyWhereString = "( " + manyToManyWhere + ")"; manyToManyWhereTemplate = renderWhereStringTemplate( manyToManyWhereString, creationContext.getDialect(), typeConfiguration ); } @@ -540,15 +498,60 @@ public AbstractCollectionPersister( tableMapping = buildCollectionTableMapping( collectionBootDescriptor, getTableName(), getCollectionSpaces() ); - cascadeDeleteEnabled = collectionBootDescriptor.getKey().isCascadeDeleteEnabled() + cascadeDeleteEnabled = + key.isCascadeDeleteEnabled() && creationContext.getDialect().supportsCascadeDelete(); } + private FilterHelper manyToManyFilterHelper(Collection collection, RuntimeModelCreationContext context) { + return collection.getManyToManyFilters().isEmpty() + ? null + : new FilterHelper( collection.getManyToManyFilters(), context.getSessionFactory() ); + } + + private FilterHelper filterHelper( + Collection collection, EntityPersister elementPersister, RuntimeModelCreationContext context) { + if ( collection.getFilters().isEmpty() ) { + return null; + } + else { + final var entityNameByTableNameMap = + elementPersister == null + ? null + : AbstractEntityPersister.getEntityNameByTableNameMap( + context.getBootModel().getEntityBinding( elementPersister.getEntityName() ), + context.getSessionFactory().getSqlStringGenerationContext() + ); + return new FilterHelper( collection.getFilters(), entityNameByTableNameMap, factory ); + } + } + + private static int batchSize(Collection collection, RuntimeModelCreationContext context) { + return collection.getBatchSize() < 0 + ? context.getSessionFactoryOptions().getDefaultBatchFetchSize() + : collection.getBatchSize(); + } + + private static CacheEntryStructure cacheEntryStructure(Collection collection, RuntimeModelCreationContext context) { + if ( context.getSessionFactoryOptions().isStructuredCacheEntriesEnabled() ) { + return collection.isMap() + ? StructuredMapCacheEntry.INSTANCE + : StructuredCollectionCacheEntry.INSTANCE; + } + else { + return UnstructuredCacheEntry.INSTANCE; + } + } + + SqlAstTranslatorFactory getSqlAstTranslatorFactory() { + return getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory(); + } + @Override public void prepareMappingModel(MappingModelCreationProcess creationProcess) { if ( mappedByProperty != null && elementType instanceof EntityType entityType ) { final String entityName = entityType.getAssociatedEntityName(); - final PersistentClass persistentClass = + final var persistentClass = creationProcess.getCreationContext().getBootModel() .getEntityBinding( entityName ); if ( persistentClass.getRecursiveProperty( mappedByProperty ).getValue() instanceof Any ) { @@ -557,8 +560,12 @@ public void prepareMappingModel(MappingModelCreationProcess creationProcess) { creationProcess.registerInitializationCallback( "Where-fragment handling for ANY inverse mapping : " + navigableRole, () -> { - final EntityPersister entityPersister = creationProcess.getEntityPersister( entityName ); - delayedWhereFragmentProcessing( entityPersister, mappedByProperty, collectionBootDescriptor, creationProcess ); + delayedWhereFragmentProcessing( + creationProcess.getEntityPersister( entityName ), + mappedByProperty, + collectionBootDescriptor, + creationProcess + ); buildStaticWhereFragmentSensitiveSql(); collectionBootDescriptor = null; return true; @@ -571,8 +578,9 @@ public void prepareMappingModel(MappingModelCreationProcess creationProcess) { if ( isNotEmpty( collectionBootDescriptor.getWhere() ) ) { hasWhere = true; sqlWhereString = "(" + collectionBootDescriptor.getWhere() + ")"; - sqlWhereStringTemplate = renderWhereStringTemplate( sqlWhereString, dialect, - creationProcess.getCreationContext().getTypeConfiguration() ); + sqlWhereStringTemplate = + renderWhereStringTemplate( sqlWhereString, dialect, + creationProcess.getCreationContext().getTypeConfiguration() ); } buildStaticWhereFragmentSensitiveSql(); collectionBootDescriptor = null; @@ -584,14 +592,14 @@ private void delayedWhereFragmentProcessing( Collection collectionBootDescriptor, MappingModelCreationProcess creationProcess) { - final AttributeMapping mappedByAttribute = resolveMappedBy( entityPersister, mappedByProperty ); - final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext(); final String where; - if ( mappedByAttribute instanceof DiscriminatedAssociationAttributeMapping anyMapping ) { - final DiscriminatorMapping discriminatorMapping = anyMapping.getDiscriminatorMapping(); - final DiscriminatorValueDetails discriminatorValueDetails = + if ( resolveMappedBy( entityPersister, mappedByProperty ) + instanceof DiscriminatedAssociationAttributeMapping anyMapping ) { + final var discriminatorMapping = anyMapping.getDiscriminatorMapping(); + final var discriminatorValueDetails = discriminatorMapping.getValueConverter() .getDetailsForEntityName( ownerPersister.getEntityName() ); + final var creationContext = creationProcess.getCreationContext(); //noinspection unchecked final String discriminatorLiteral = discriminatorMapping.getUnderlyingJdbcMapping() @@ -610,8 +618,9 @@ private void delayedWhereFragmentProcessing( if ( isNotEmpty( where ) ) { hasWhere = true; sqlWhereString = "(" + where + ")"; - sqlWhereStringTemplate = renderWhereStringTemplate( sqlWhereString, dialect, - creationContext.getTypeConfiguration() ); + sqlWhereStringTemplate = + renderWhereStringTemplate( sqlWhereString, dialect, + creationProcess.getCreationContext().getTypeConfiguration() ); } } @@ -626,32 +635,31 @@ private boolean isMap() { } private static AttributeMapping resolveMappedBy(EntityPersister entityPersister, String mappedByProperty) { - final StringTokenizer propertyPathParts = new StringTokenizer( mappedByProperty, ".", false ); - assert propertyPathParts.countTokens() > 0; - - if ( propertyPathParts.countTokens() == 1 ) { + final var propertyPathParts = new StringTokenizer( mappedByProperty, ".", false ); + final int tokenCount = propertyPathParts.countTokens(); + assert tokenCount > 0; + if ( tokenCount == 1 ) { return entityPersister.findAttributeMapping( propertyPathParts.nextToken() ); } - - ManagedMappingType source = entityPersister; - while ( propertyPathParts.hasMoreTokens() ) { - final String partName = propertyPathParts.nextToken(); - final AttributeMapping namedPart = source.findAttributeMapping( partName ); - if ( !propertyPathParts.hasMoreTokens() ) { - return namedPart; + else { + ManagedMappingType source = entityPersister; + while ( propertyPathParts.hasMoreTokens() ) { + final String partName = propertyPathParts.nextToken(); + final var namedPart = source.findAttributeMapping( partName ); + if ( !propertyPathParts.hasMoreTokens() ) { + return namedPart; + } + source = (ManagedMappingType) namedPart.getPartMappingType(); } - - source = (ManagedMappingType) namedPart.getPartMappingType(); + throw new MappingException( + String.format( + Locale.ROOT, + "Unable to resolve mapped-by path : (%s) %s", + entityPersister.getEntityName(), + mappedByProperty + ) + ); } - - throw new MappingException( - String.format( - Locale.ROOT, - "Unable to resolve mapped-by path : (%s) %s", - entityPersister.getEntityName(), - mappedByProperty - ) - ); } private BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) { @@ -665,7 +673,7 @@ private BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext con } private boolean shouldUseShallowCacheLayout(CacheLayout collectionQueryCacheLayout, SessionFactoryOptions options) { - final CacheLayout queryCacheLayout = + final var queryCacheLayout = collectionQueryCacheLayout == null ? options.getQueryCacheLayout() : collectionQueryCacheLayout; @@ -704,7 +712,7 @@ public void postInstantiate() throws MappingException { } private NamedQueryMemento getNamedQueryMemento(MetadataImplementor bootModel) { - final NamedQueryMemento memento = + final var memento = factory.getQueryEngine().getNamedObjectRepository() .resolve( factory, bootModel, queryLoaderName ); if ( memento == null ) { @@ -718,19 +726,21 @@ protected void logStaticSQL() { if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) { MODEL_MUTATION_LOGGER.tracef( "Static SQL for collection: %s", getRole() ); - final JdbcMutationOperation insertRowOperation = getRowMutationOperations().getInsertRowOperation(); + final var rowMutationOperations = getRowMutationOperations(); + + final var insertRowOperation = rowMutationOperations.getInsertRowOperation(); final String insertRowSql = insertRowOperation != null ? insertRowOperation.getSqlString() : null; if ( insertRowSql != null ) { MODEL_MUTATION_LOGGER.tracef( " Row insert: %s", insertRowSql ); } - final JdbcMutationOperation updateRowOperation = getRowMutationOperations().getUpdateRowOperation(); + final var updateRowOperation = rowMutationOperations.getUpdateRowOperation(); final String updateRowSql = updateRowOperation != null ? updateRowOperation.getSqlString() : null; if ( updateRowSql != null ) { MODEL_MUTATION_LOGGER.tracef( " Row update: %s", updateRowSql ); } - final JdbcMutationOperation deleteRowOperation = getRowMutationOperations().getDeleteRowOperation(); + final var deleteRowOperation = rowMutationOperations.getDeleteRowOperation(); final String deleteRowSql = deleteRowOperation != null ? deleteRowOperation.getSqlString() : null; if ( deleteRowSql != null ) { MODEL_MUTATION_LOGGER.tracef( " Row delete: %s", deleteRowSql ); @@ -778,9 +788,9 @@ protected CollectionLoader determineLoaderToUse(Object key, SharedSessionContrac return getCollectionLoader(); } else { - final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers(); + final var influencers = session.getLoadQueryInfluencers(); if ( influencers.effectiveSubselectFetchEnabled( this ) ) { - final CollectionLoader subSelectLoader = resolveSubSelectLoader( key, session ); + final var subSelectLoader = resolveSubSelectLoader( key, session ); if ( subSelectLoader != null ) { return subSelectLoader; } @@ -792,8 +802,8 @@ protected CollectionLoader determineLoaderToUse(Object key, SharedSessionContrac } private CollectionLoader resolveSubSelectLoader(Object key, SharedSessionContractImplementor session) { - final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); - final SubselectFetch subselect = + final var persistenceContext = session.getPersistenceContextInternal(); + final var subselect = persistenceContext.getBatchFetchQueue() .getSubselect( session.generateEntityKey( key, getOwnerEntityPersister() ) ); if ( subselect == null ) { @@ -920,9 +930,9 @@ public String getIdentifierColumnName() { */ @Override public String selectFragment(String alias, String columnSuffix) { - final PluralAttributeMapping attributeMapping = getAttributeMapping(); - final QuerySpec rootQuerySpec = new QuerySpec( true ); - final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState( + final var attributeMapping = getAttributeMapping(); + final var rootQuerySpec = new QuerySpec( true ); + final var sqlAstCreationState = new LoaderSqlAstCreationState( rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), @@ -933,8 +943,8 @@ public String selectFragment(String alias, String columnSuffix) { factory.getSqlTranslationEngine() ); - final NavigablePath entityPath = new NavigablePath( attributeMapping.getRootPathName() ); - final TableGroup rootTableGroup = attributeMapping.createRootTableGroup( + final var entityPath = new NavigablePath( attributeMapping.getRootPathName() ); + final var rootTableGroup = attributeMapping.createRootTableGroup( true, entityPath, null, @@ -949,15 +959,15 @@ public String selectFragment(String alias, String columnSuffix) { attributeMapping.createDomainResult( entityPath, rootTableGroup, null, sqlAstCreationState ); // Wrap expressions with aliases - final SelectClause selectClause = rootQuerySpec.getSelectClause(); - final java.util.List sqlSelections = selectClause.getSqlSelections(); + final var sqlSelections = rootQuerySpec.getSelectClause().getSqlSelections(); int i = 0; for ( String keyAlias : keyColumnAliases ) { sqlSelections.set( i, new SqlSelectionImpl( i, - new AliasedExpression( sqlSelections.get( i ).getExpression(), keyAlias + columnSuffix ) + new AliasedExpression( sqlSelections.get( i ).getExpression(), + keyAlias + columnSuffix ) ) ); i++; @@ -969,7 +979,8 @@ public String selectFragment(String alias, String columnSuffix) { i, new SqlSelectionImpl( i, - new AliasedExpression( sqlSelections.get( i ).getExpression(), indexAlias + columnSuffix ) + new AliasedExpression( sqlSelections.get( i ).getExpression(), + indexAlias + columnSuffix ) ) ); i++; @@ -980,25 +991,27 @@ public String selectFragment(String alias, String columnSuffix) { i, new SqlSelectionImpl( i, - new AliasedExpression( sqlSelections.get( i ).getExpression(), identifierColumnAlias + columnSuffix ) + new AliasedExpression( sqlSelections.get( i ).getExpression(), + identifierColumnAlias + columnSuffix ) ) ); i++; } for ( int columnIndex = 0; i < sqlSelections.size(); i++, columnIndex++ ) { - final SqlSelection sqlSelection = sqlSelections.get( i ); + final var sqlSelection = sqlSelections.get( i ); sqlSelections.set( i, new SqlSelectionImpl( sqlSelection.getValuesArrayPosition(), - new AliasedExpression( sqlSelection.getExpression(), elementColumnAliases[columnIndex] + columnSuffix ) + new AliasedExpression( sqlSelection.getExpression(), + elementColumnAliases[columnIndex] + columnSuffix ) ) ); } final String sql = - getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory() + getSqlAstTranslatorFactory() .buildSelectTranslator( getFactory(), new SelectStatement( rootQuerySpec ) ) .translate( null, QueryOptions.NONE ) .getSqlString(); @@ -1009,9 +1022,9 @@ public String selectFragment(String alias, String columnSuffix) { } protected String generateSelectSizeString(boolean isIntegerIndexed) { - String selectValue = isIntegerIndexed ? - "max(" + getIndexColumnNames()[0] + ") + 1" : // lists, arrays - "count(" + getElementColumnNames()[0] + ")"; // sets, maps, bags + final String selectValue = isIntegerIndexed + ? "max(" + getIndexColumnNames()[0] + ") + 1" // lists, arrays + : "count(" + getElementColumnNames()[0] + ")"; // sets, maps, bags return new SimpleSelect( getFactory() ) .setTableName( getTableName() ) .addRestriction( getKeyColumnNames() ) @@ -1024,14 +1037,16 @@ protected String generateDetectRowByIndexString() { if ( !hasIndex() ) { return null; } - return new SimpleSelect( getFactory() ) - .setTableName( getTableName() ) - .addRestriction( getKeyColumnNames() ) - .addRestriction( getIndexColumnNames() ) - .addRestriction( indexFormulas ) - .addWhereToken( sqlWhereString ) - .addColumn( "1" ) - .toStatementString(); + else { + return new SimpleSelect( getFactory() ) + .setTableName( getTableName() ) + .addRestriction( getKeyColumnNames() ) + .addRestriction( getIndexColumnNames() ) + .addRestriction( indexFormulas ) + .addWhereToken( sqlWhereString ) + .addColumn( "1" ) + .toStatementString(); + } } @@ -1164,34 +1179,30 @@ public boolean hasWhereRestrictions() { return hasWhere || manyToManyWhereTemplate != null; } - @Override - public void applyWhereRestrictions( - Consumer predicateConsumer, - TableGroup tableGroup, - boolean useQualifier, - SqlAstCreationState creationState) { - final TableReference tableReference; - if ( isManyToMany() ) { - tableReference = tableGroup.getPrimaryTableReference(); - } - else if ( elementPersister != null ) { - tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), elementPersister.getTableName() ); - } - else { - tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), qualifiedTableName ); - } - - final String alias; + private static String aliasForWhereRestriction(TableReference tableReference, boolean useQualifier) { if ( tableReference == null ) { - alias = null; + return null; } else if ( useQualifier && tableReference.getIdentificationVariable() != null ) { - alias = tableReference.getIdentificationVariable(); + return tableReference.getIdentificationVariable(); } else { - alias = tableReference.getTableId(); + return tableReference.getTableId(); } + } + @Override + public void applyWhereRestrictions( + Consumer predicateConsumer, + TableGroup tableGroup, + boolean useQualifier, + SqlAstCreationState creationState) { + final var tableReference = + isManyToMany() + ? tableGroup.getPrimaryTableReference() + : tableGroup.getTableReference( tableGroup.getNavigablePath(), + elementPersister != null ? elementPersister.getTableName() : qualifiedTableName ); + final String alias = aliasForWhereRestriction( tableReference, useQualifier ); applyWhereFragments( predicateConsumer, alias, tableGroup, creationState ); } @@ -1207,16 +1218,12 @@ protected void applyWhereFragments( * Applies all defined {@link org.hibernate.annotations.SQLRestriction} */ private static void applyWhereFragments(Consumer predicateConsumer, String alias, String template) { - if ( template == null ) { - return; - } - - final String fragment = replace( template, Template.TEMPLATE, alias ); - if ( isEmpty( fragment ) ) { - return; + if ( template != null ) { + final String fragment = replace( template, Template.TEMPLATE, alias ); + if ( !isEmpty( fragment ) ) { + predicateConsumer.accept( new SqlFragmentPredicate( fragment ) ); + } } - - predicateConsumer.accept( new SqlFragmentPredicate( fragment ) ); } @Override @@ -1250,50 +1257,32 @@ public void applyBaseManyToManyRestrictions( Map enabledFilters, Set treatAsDeclarations, SqlAstCreationState creationState) { - if ( manyToManyFilterHelper == null && manyToManyWhereTemplate == null ) { - return; - } - - - if ( manyToManyFilterHelper != null ) { - final FilterAliasGenerator aliasGenerator = elementPersister.getFilterAliasGenerator( tableGroup ); - manyToManyFilterHelper.applyEnabledFilters( - predicateConsumer, - aliasGenerator, - enabledFilters, - false, - tableGroup, - creationState - ); - } - - if ( manyToManyWhereString != null ) { - final TableReference tableReference = tableGroup.resolveTableReference( elementPersister.getTableName() ); - - final String alias; - if ( tableReference == null ) { - alias = null; + if ( manyToManyFilterHelper != null || manyToManyWhereTemplate != null ) { + if ( manyToManyFilterHelper != null ) { + manyToManyFilterHelper.applyEnabledFilters( + predicateConsumer, + elementPersister.getFilterAliasGenerator( tableGroup ), + enabledFilters, + false, + tableGroup, + creationState + ); } - else if ( useQualifier && tableReference.getIdentificationVariable() != null ) { - alias = tableReference.getIdentificationVariable(); + if ( manyToManyWhereString != null ) { + final var tableReference = tableGroup.resolveTableReference( elementPersister.getTableName() ); + final String alias = aliasForWhereRestriction( tableReference, useQualifier ); + applyWhereFragments( predicateConsumer, alias, manyToManyWhereTemplate ); } - else { - alias = tableReference.getTableId(); - } - - applyWhereFragments( predicateConsumer, alias, manyToManyWhereTemplate ); } } @Override public String getManyToManyFilterFragment(TableGroup tableGroup, Map enabledFilters) { - final StringBuilder fragment = new StringBuilder(); - + final var fragment = new StringBuilder(); if ( manyToManyFilterHelper != null ) { manyToManyFilterHelper.render( fragment, elementPersister.getFilterAliasGenerator( tableGroup ), enabledFilters ); } - if ( manyToManyWhereString != null ) { if ( !fragment.isEmpty() ) { fragment.append( " and " ); @@ -1303,7 +1292,6 @@ public String getManyToManyFilterFragment(TableGroup tableGroup, Map(), attributeMapping.getElementDescriptor(), influencers, true ) ) { return new CollectionElementLoaderByIndex( attributeMapping, influencers, factory ) .load( key, index, session ); @@ -1576,10 +1563,10 @@ public boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) { @Override public boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers, boolean onlyApplyForLoadByKeyFilters) { if ( influencers.hasEnabledFilters() ) { - final Map enabledFilters = influencers.getEnabledFilters(); + final var enabledFilters = influencers.getEnabledFilters(); return filterHelper != null && filterHelper.isAffectedBy( enabledFilters ) - || manyToManyFilterHelper != null && manyToManyFilterHelper.isAffectedBy( enabledFilters ) - || isKeyOrElementAffectedByFilters( new HashSet<>(), influencers, onlyApplyForLoadByKeyFilters); + || manyToManyFilterHelper != null && manyToManyFilterHelper.isAffectedBy( enabledFilters ) + || isKeyOrElementAffectedByFilters( new HashSet<>(), influencers, onlyApplyForLoadByKeyFilters); } else { return false; @@ -1592,10 +1579,10 @@ public boolean isAffectedByEnabledFilters( LoadQueryInfluencers influencers, boolean onlyApplyForLoadByKeyFilters) { if ( influencers.hasEnabledFilters() ) { - final Map enabledFilters = influencers.getEnabledFilters(); + final var enabledFilters = influencers.getEnabledFilters(); return filterHelper != null && filterHelper.isAffectedBy( enabledFilters ) - || manyToManyFilterHelper != null && manyToManyFilterHelper.isAffectedBy( enabledFilters ) - || isKeyOrElementAffectedByFilters( visitedTypes, influencers, onlyApplyForLoadByKeyFilters); + || manyToManyFilterHelper != null && manyToManyFilterHelper.isAffectedBy( enabledFilters ) + || isKeyOrElementAffectedByFilters( visitedTypes, influencers, onlyApplyForLoadByKeyFilters); } else { return false; @@ -1607,7 +1594,7 @@ private boolean isKeyOrElementAffectedByFilters( LoadQueryInfluencers influencers, boolean onlyApplyForLoadByKey) { return isAffectedByFilters( visitedTypes, attributeMapping.getIndexDescriptor(), influencers, onlyApplyForLoadByKey ) - || isAffectedByFilters( visitedTypes, attributeMapping.getElementDescriptor(), influencers, onlyApplyForLoadByKey ); + || isAffectedByFilters( visitedTypes, attributeMapping.getElementDescriptor(), influencers, onlyApplyForLoadByKey ); } private boolean isAffectedByFilters( @@ -1620,8 +1607,8 @@ private boolean isAffectedByFilters( .isAffectedByEnabledFilters( visitedTypes, influencers, onlyApplyForLoadByKey ); } else if ( collectionPart instanceof EmbeddedCollectionPart embeddedCollectionPart ) { - final EmbeddableMappingType type = embeddedCollectionPart.getEmbeddableTypeDescriptor(); - return type.isAffectedByEnabledFilters( visitedTypes, influencers, onlyApplyForLoadByKey ); + return embeddedCollectionPart.getEmbeddableTypeDescriptor() + .isAffectedByEnabledFilters( visitedTypes, influencers, onlyApplyForLoadByKey ); } else { return false; @@ -1723,14 +1710,12 @@ protected JdbcMutationOperation buildDeleteAllOperation(MutatingTableReference t } private JdbcDeleteMutation buildCustomSqlDeleteAllOperation(MutatingTableReference tableReference) { - final PluralAttributeMapping attributeMapping = getAttributeMapping(); - final ForeignKeyDescriptor keyDescriptor = attributeMapping.getKeyDescriptor(); - - final ColumnValueParameterList parameterBinders = + final var attributeMapping = getAttributeMapping(); + final var keyDescriptor = attributeMapping.getKeyDescriptor(); + final var parameterBinders = new ColumnValueParameterList( tableReference, ParameterUsage.RESTRICT, keyDescriptor.getJdbcTypeCount() ); keyDescriptor.getKeyPart().forEachSelectable( parameterBinders ); - - final TableMapping tableMapping = tableReference.getTableMapping(); + final var tableMapping = tableReference.getTableMapping(); return new JdbcDeleteMutation( tableMapping, this, @@ -1742,23 +1727,20 @@ private JdbcDeleteMutation buildCustomSqlDeleteAllOperation(MutatingTableReferen } private JdbcMutationOperation buildGeneratedDeleteAllOperation(MutatingTableReference tableReference) { - return getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory() + return getSqlAstTranslatorFactory() .buildModelMutationTranslator( generateDeleteAllAst( tableReference ), getFactory() ) .translate( null, MutationQueryOptions.INSTANCE ); } public RestrictedTableMutation generateDeleteAllAst(MutatingTableReference tableReference) { assert getAttributeMapping() != null; - - final ForeignKeyDescriptor fkDescriptor = getAttributeMapping().getKeyDescriptor(); - assert fkDescriptor != null; - - final int keyColumnCount = fkDescriptor.getJdbcTypeCount(); - final ColumnValueParameterList parameterBinders = + final var foreignKeyDescriptor = getAttributeMapping().getKeyDescriptor(); + assert foreignKeyDescriptor != null; + final int keyColumnCount = foreignKeyDescriptor.getJdbcTypeCount(); + final var parameterBinders = new ColumnValueParameterList( tableReference, ParameterUsage.RESTRICT, keyColumnCount ); - final java.util.List restrictionBindings = arrayList( keyColumnCount ); - applyKeyRestrictions( tableReference, parameterBinders, restrictionBindings ); - + final List restrictionBindings = arrayList( keyColumnCount ); + applyKeyRestrictions( parameterBinders, restrictionBindings ); //noinspection unchecked,rawtypes return (RestrictedTableMutation) new TableDeleteStandard( tableReference, @@ -1772,16 +1754,13 @@ public RestrictedTableMutation generateDeleteAllAst(Mutat } protected void applyKeyRestrictions( - MutatingTableReference tableReference, ColumnValueParameterList parameterList, - java.util.List restrictionBindings) { - - final ForeignKeyDescriptor fkDescriptor = getAttributeMapping().getKeyDescriptor(); - assert fkDescriptor != null; - - fkDescriptor.getKeyPart().forEachSelectable( parameterList ); - for ( ColumnValueParameter columnValueParameter : parameterList ) { - final ColumnReference columnReference = columnValueParameter.getColumnReference(); + List restrictionBindings) { + final var foreignKeyDescriptor = getAttributeMapping().getKeyDescriptor(); + assert foreignKeyDescriptor != null; + foreignKeyDescriptor.getKeyPart().forEachSelectable( parameterList ); + for ( var columnValueParameter : parameterList ) { + final var columnReference = columnValueParameter.getColumnReference(); restrictionBindings.add( new ColumnValueBinding( columnReference, 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 8f8a2a2ac690..5b6715ab76b9 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 @@ -16,14 +16,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.StaticFilterAliasGenerator; -import org.hibernate.internal.util.MutableInteger; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Collection; -import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor; -import org.hibernate.metamodel.mapping.CollectionPart; -import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; -import org.hibernate.metamodel.mapping.PluralAttributeMapping; -import org.hibernate.metamodel.mapping.SoftDeleteMapping; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.collection.mutation.DeleteRowsCoordinator; import org.hibernate.persister.collection.mutation.DeleteRowsCoordinatorNoOp; @@ -39,14 +32,12 @@ import org.hibernate.persister.collection.mutation.UpdateRowsCoordinator; import org.hibernate.persister.collection.mutation.UpdateRowsCoordinatorNoOp; import org.hibernate.persister.collection.mutation.UpdateRowsCoordinatorStandard; -import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.model.ast.ColumnValueBinding; import org.hibernate.sql.model.ast.ColumnValueParameterList; import org.hibernate.sql.model.ast.MutatingTableReference; import org.hibernate.sql.model.ast.RestrictedTableMutation; -import org.hibernate.sql.model.ast.TableInsert; import org.hibernate.sql.model.ast.TableMutation; import org.hibernate.sql.model.ast.builder.CollectionRowDeleteBuilder; import org.hibernate.sql.model.ast.builder.TableInsertBuilderStandard; @@ -57,6 +48,7 @@ import java.util.List; +import static org.hibernate.internal.util.collections.ArrayHelper.isAnyTrue; import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; /** @@ -79,11 +71,10 @@ public class BasicCollectionPersister extends AbstractCollectionPersister { public BasicCollectionPersister( Collection collectionBinding, CollectionDataAccess cacheAccessStrategy, - RuntimeModelCreationContext creationContext) throws MappingException, CacheException { + RuntimeModelCreationContext creationContext) + throws MappingException, CacheException { super( collectionBinding, cacheAccessStrategy, creationContext ); - this.rowMutationOperations = buildRowMutationOperations(); - this.insertRowsCoordinator = buildInsertRowCoordinator(); this.updateCoordinator = buildUpdateRowCoordinator(); this.deleteRowsCoordinator = buildDeleteRowCoordinator(); @@ -138,9 +129,10 @@ protected void doProcessQueuedOps(PersistentCollection collection, Object id, private UpdateRowsCoordinator buildUpdateRowCoordinator() { - final boolean performUpdates = getCollectionSemantics().getCollectionClassification().isRowUpdatePossible() - && ArrayHelper.isAnyTrue( elementColumnIsSettable ) - && !isInverse(); + final boolean performUpdates = + getCollectionSemantics().getCollectionClassification().isRowUpdatePossible() + && isAnyTrue( elementColumnIsSettable ) + && !isInverse(); if ( !performUpdates ) { // if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) { @@ -151,8 +143,13 @@ private UpdateRowsCoordinator buildUpdateRowCoordinator() { // } return new UpdateRowsCoordinatorNoOp( this ); } - - return new UpdateRowsCoordinatorStandard( this, rowMutationOperations, getFactory() ); + else { + return new UpdateRowsCoordinatorStandard( + this, + rowMutationOperations, + getFactory() + ); + } } private InsertRowsCoordinator buildInsertRowCoordinator() { @@ -165,12 +162,17 @@ private InsertRowsCoordinator buildInsertRowCoordinator() { // } return new InsertRowsCoordinatorNoOp( this ); } - - return new InsertRowsCoordinatorStandard( this, rowMutationOperations, getFactory().getServiceRegistry() ); + else { + return new InsertRowsCoordinatorStandard( + this, + rowMutationOperations, + getFactory().getServiceRegistry() + ); + } } private DeleteRowsCoordinator buildDeleteRowCoordinator() { - if ( ! needsRemove() ) { + if ( !needsRemove() ) { // if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) { // MODEL_MUTATION_LOGGER.tracef( // "Skipping collection row deletions - %s", @@ -179,12 +181,18 @@ private DeleteRowsCoordinator buildDeleteRowCoordinator() { // } return new DeleteRowsCoordinatorNoOp( this ); } - - return new DeleteRowsCoordinatorStandard( this, rowMutationOperations, hasPhysicalIndexColumn(), getFactory().getServiceRegistry() ); + else { + return new DeleteRowsCoordinatorStandard( + this, + rowMutationOperations, + hasPhysicalIndexColumn(), + getFactory().getServiceRegistry() + ); + } } private RemoveCoordinator buildDeleteAllCoordinator() { - if ( ! needsRemove() ) { + if ( !needsRemove() ) { // if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) { // MODEL_MUTATION_LOGGER.tracef( // "Skipping collection removals - %s", @@ -193,44 +201,44 @@ private RemoveCoordinator buildDeleteAllCoordinator() { // } return new RemoveCoordinatorNoOp( this ); } - - return new RemoveCoordinatorStandard( this, this::buildDeleteAllOperation, getFactory().getServiceRegistry() ); + else { + return new RemoveCoordinatorStandard( + this, + this::buildDeleteAllOperation, + getFactory().getServiceRegistry() + ); + } } @Override public RestrictedTableMutation generateDeleteAllAst(MutatingTableReference tableReference) { - assert getAttributeMapping() != null; - - final SoftDeleteMapping softDeleteMapping = getAttributeMapping().getSoftDeleteMapping(); + final var attributeMapping = getAttributeMapping(); + assert attributeMapping != null; + final var softDeleteMapping = attributeMapping.getSoftDeleteMapping(); if ( softDeleteMapping == null ) { return super.generateDeleteAllAst( tableReference ); } - - final ForeignKeyDescriptor fkDescriptor = getAttributeMapping().getKeyDescriptor(); - assert fkDescriptor != null; - - final int keyColumnCount = fkDescriptor.getJdbcTypeCount(); - final ColumnValueParameterList parameterBinders = new ColumnValueParameterList( - tableReference, - ParameterUsage.RESTRICT, - keyColumnCount - ); - final java.util.List restrictionBindings = arrayList( keyColumnCount ); - applyKeyRestrictions( tableReference, parameterBinders, restrictionBindings ); - - final ColumnReference softDeleteColumn = new ColumnReference( tableReference, softDeleteMapping ); - final ColumnValueBinding nonDeletedBinding = softDeleteMapping.createNonDeletedValueBinding( softDeleteColumn ); - final ColumnValueBinding deletedBinding = softDeleteMapping.createDeletedValueBinding( softDeleteColumn ); - - return new TableUpdateStandard( - tableReference, - this, - "soft-delete removal", - List.of( deletedBinding ), - restrictionBindings, - List.of( nonDeletedBinding ) - ); + else { + final var foreignKeyDescriptor = attributeMapping.getKeyDescriptor(); + assert foreignKeyDescriptor != null; + final int keyColumnCount = foreignKeyDescriptor.getJdbcTypeCount(); + final var parameterBinders = + new ColumnValueParameterList( tableReference, ParameterUsage.RESTRICT, keyColumnCount ); + final List restrictionBindings = arrayList( keyColumnCount ); + applyKeyRestrictions( parameterBinders, restrictionBindings ); + final var softDeleteColumn = new ColumnReference( tableReference, softDeleteMapping ); + final var nonDeletedBinding = softDeleteMapping.createNonDeletedValueBinding( softDeleteColumn ); + final var deletedBinding = softDeleteMapping.createDeletedValueBinding( softDeleteColumn ); + return new TableUpdateStandard( + tableReference, + this, + "soft-delete removal", + List.of( deletedBinding ), + restrictionBindings, + List.of( nonDeletedBinding ) + ); + } } protected RowMutationOperations buildRowMutationOperations() { @@ -249,7 +257,7 @@ protected RowMutationOperations buildRowMutationOperations() { final RowMutationOperations.Values updateRowValues; final RowMutationOperations.Restrictions updateRowRestrictions; if ( getCollectionSemantics().getCollectionClassification().isRowUpdatePossible() - && ArrayHelper.isAnyTrue( elementColumnIsSettable ) + && isAnyTrue( elementColumnIsSettable ) && !isInverse() ) { updateRowOperationProducer = this::generateUpdateRowOperation; updateRowValues = this::applyUpdateRowValues; @@ -291,67 +299,51 @@ protected RowMutationOperations buildRowMutationOperations() { // Insert handling private JdbcMutationOperation generateInsertRowOperation(MutatingTableReference tableReference) { - if ( getIdentifierTableMapping().getInsertDetails().getCustomSql() != null ) { - return buildCustomSqlInsertRowOperation( tableReference ); - } - - return buildGeneratedInsertRowOperation( tableReference ); + return getIdentifierTableMapping().getInsertDetails().getCustomSql() != null + ? buildCustomSqlInsertRowOperation( tableReference ) + : buildGeneratedInsertRowOperation( tableReference ); } private JdbcMutationOperation buildCustomSqlInsertRowOperation(MutatingTableReference tableReference) { - final TableInsertBuilderStandard insertBuilder = new TableInsertBuilderStandard( this, tableReference, getFactory() ); + final var factory = getFactory(); + final var insertBuilder = new TableInsertBuilderStandard( this, tableReference, factory ); applyInsertDetails( insertBuilder ); - - final TableInsert tableInsert = insertBuilder.buildMutation(); - return tableInsert.createMutationOperation( null, getFactory() ); + return insertBuilder.buildMutation().createMutationOperation( null, factory ); } private void applyInsertDetails(TableInsertBuilderStandard insertBuilder) { - final PluralAttributeMapping attributeMapping = getAttributeMapping(); - - final ForeignKeyDescriptor foreignKey = attributeMapping.getKeyDescriptor(); - foreignKey.getKeyPart().forEachSelectable( insertBuilder ); - - final CollectionIdentifierDescriptor identifierDescriptor = attributeMapping.getIdentifierDescriptor(); - final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor(); + final var attributeMapping = getAttributeMapping(); + attributeMapping.getKeyDescriptor().getKeyPart().forEachSelectable( insertBuilder ); + final var identifierDescriptor = attributeMapping.getIdentifierDescriptor(); + final var indexDescriptor = attributeMapping.getIndexDescriptor(); if ( identifierDescriptor != null ) { identifierDescriptor.forEachSelectable( insertBuilder ); } else if ( indexDescriptor != null ) { indexDescriptor.forEachInsertable( insertBuilder ); } - attributeMapping.getElementDescriptor().forEachInsertable( insertBuilder ); - - final SoftDeleteMapping softDeleteMapping = getAttributeMapping().getSoftDeleteMapping(); + final var softDeleteMapping = attributeMapping.getSoftDeleteMapping(); if ( softDeleteMapping != null ) { - final ColumnReference columnReference = new ColumnReference( insertBuilder.getMutatingTable(), softDeleteMapping ); + final var columnReference = new ColumnReference( insertBuilder.getMutatingTable(), softDeleteMapping ); insertBuilder.addValueColumn( softDeleteMapping.createNonDeletedValueBinding( columnReference ) ); } } private JdbcMutationOperation buildGeneratedInsertRowOperation(MutatingTableReference tableReference) { - final TableMutation sqlAst = generateInsertRowAst( tableReference ); - - final SqlAstTranslator translator = getFactory().getJdbcServices() - .getDialect() - .getSqlAstTranslatorFactory() - .buildModelMutationTranslator( sqlAst, getFactory() ); - - return translator.translate( null, MutationQueryOptions.INSTANCE ); + return getSqlAstTranslatorFactory() + .buildModelMutationTranslator( generateInsertRowAst( tableReference ), getFactory() ) + .translate( null, MutationQueryOptions.INSTANCE ); } private TableMutation generateInsertRowAst(MutatingTableReference tableReference) { - final PluralAttributeMapping pluralAttribute = getAttributeMapping(); + final var pluralAttribute = getAttributeMapping(); assert pluralAttribute != null; - - final ForeignKeyDescriptor fkDescriptor = pluralAttribute.getKeyDescriptor(); - assert fkDescriptor != null; - - final TableInsertBuilderStandard insertBuilder = new TableInsertBuilderStandard( this, tableReference, getFactory() ); + final var foreignKeyDescriptor = pluralAttribute.getKeyDescriptor(); + assert foreignKeyDescriptor != null; + final var insertBuilder = new TableInsertBuilderStandard( this, tableReference, getFactory() ); applyInsertDetails( insertBuilder ); - //noinspection unchecked,rawtypes return (TableMutation) insertBuilder.buildMutation(); } @@ -363,14 +355,12 @@ private void applyInsertRowValues( int rowPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - final PluralAttributeMapping attributeMapping = getAttributeMapping(); - if ( key == null ) { throw new IllegalArgumentException( "null key for collection: " + getNavigableRole().getFullPath() ); } - - final ForeignKeyDescriptor foreignKey = attributeMapping.getKeyDescriptor(); - foreignKey.getKeyPart().decompose( + final var attributeMapping = getAttributeMapping(); + final var foreignKeyDescriptor = attributeMapping.getKeyDescriptor(); + foreignKeyDescriptor.getKeyPart().decompose( key, 0, jdbcValueBindings, @@ -379,10 +369,8 @@ private void applyInsertRowValues( session ); - final MutableInteger columnPositionCount = new MutableInteger(); - if ( attributeMapping.getIdentifierDescriptor() != null ) { - getAttributeMapping().getIdentifierDescriptor().decompose( + attributeMapping.getIdentifierDescriptor().decompose( collection.getIdentifier( rowValue, rowPosition ), 0, jdbcValueBindings, @@ -399,26 +387,22 @@ else if ( attributeMapping.getIndexDescriptor() != null ) { // 1) not the managed-type structure from ModelPart // 2) not BasicType from ValueMapping // essentially any basic or composite mapping of column(s) - - getAttributeMapping().getIndexDescriptor().decompose( + attributeMapping.getIndexDescriptor().decompose( incrementIndexByBase( collection.getIndex( rowValue, rowPosition, this ) ), 0, indexColumnIsSettable, jdbcValueBindings, (valueIndex, settable, bindings, jdbcValue, jdbcValueMapping) -> { - if ( !jdbcValueMapping.getContainingTableExpression().equals( getTableName() ) ) { - // indicates a many-to-many mapping and the index is contained on the - // associated entity table - we skip it here - return; - } - if ( settable[valueIndex] ) { - bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.SET ); + if ( jdbcValueMapping.getContainingTableExpression().equals( getTableName() ) ) { + if ( settable[valueIndex] ) { + bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.SET ); + } } + // otherwise a many-to-many mapping and the index is defined + // on the associated entity table - we skip it here }, session ); - - columnPositionCount.set( 0 ); } attributeMapping.getElementDescriptor().decompose( @@ -440,22 +424,17 @@ else if ( attributeMapping.getIndexDescriptor() != null ) { // Update handling private JdbcMutationOperation generateUpdateRowOperation(MutatingTableReference tableReference) { - final RestrictedTableMutation sqlAst = generateUpdateRowAst( tableReference ); - - final SqlAstTranslator translator = getFactory().getJdbcServices() - .getDialect() - .getSqlAstTranslatorFactory() - .buildModelMutationTranslator( sqlAst, getFactory() ); - - return translator.translate( null, MutationQueryOptions.INSTANCE ); + return getSqlAstTranslatorFactory() + .buildModelMutationTranslator( generateUpdateRowAst( tableReference ), getFactory() ) + .translate( null, MutationQueryOptions.INSTANCE ); } private RestrictedTableMutation generateUpdateRowAst(MutatingTableReference tableReference) { - final PluralAttributeMapping attribute = getAttributeMapping(); + final var attribute = getAttributeMapping(); assert attribute != null; - // note that custom sql update row details are handled by TableUpdateBuilderStandard - final TableUpdateBuilderStandard updateBuilder = new TableUpdateBuilderStandard<>( + // note that custom SQL update row details are handled by TableUpdateBuilderStandard + final var updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory(), @@ -475,7 +454,6 @@ private RestrictedTableMutation generateUpdateRowAst(Muta } else { updateBuilder.addKeyRestrictionsLeniently( attribute.getKeyDescriptor().getKeyPart() ); - if ( attribute.getIndexDescriptor() != null && !indexContainsFormula ) { updateBuilder.addKeyRestrictionsLeniently( attribute.getIndexDescriptor() ); } @@ -495,22 +473,15 @@ private void applyUpdateRowValues( int entryPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - final Object element = collection.getElement( entry ); - final CollectionPart elementDescriptor = getAttributeMapping().getElementDescriptor(); - elementDescriptor.decompose( - element, + getAttributeMapping().getElementDescriptor().decompose( + collection.getElement( entry ), 0, jdbcValueBindings, null, (valueIndex, bindings, y, jdbcValue, jdbcValueMapping) -> { - if ( !jdbcValueMapping.isUpdateable() || jdbcValueMapping.isFormula() ) { - return; + if ( jdbcValueMapping.isUpdateable() && !jdbcValueMapping.isFormula() ) { + bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.SET ); } - bindings.bindValue( - jdbcValue, - jdbcValueMapping, - ParameterUsage.SET - ); }, session ); @@ -523,11 +494,10 @@ private void applyUpdateRowRestrictions( int entryPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - if ( getAttributeMapping().getIdentifierDescriptor() != null ) { - final CollectionIdentifierDescriptor identifierDescriptor = getAttributeMapping().getIdentifierDescriptor(); - final Object identifier = collection.getIdentifier( entry, entryPosition ); - identifierDescriptor.decompose( - identifier, + final var attributeMapping = getAttributeMapping(); + if ( attributeMapping.getIdentifierDescriptor() != null ) { + attributeMapping.getIdentifierDescriptor().decompose( + collection.getIdentifier( entry, entryPosition ), 0, jdbcValueBindings, null, @@ -536,7 +506,7 @@ private void applyUpdateRowRestrictions( ); } else { - getAttributeMapping().getKeyDescriptor().getKeyPart().decompose( + attributeMapping.getKeyDescriptor().getKeyPart().decompose( key, 0, jdbcValueBindings, @@ -545,10 +515,12 @@ private void applyUpdateRowRestrictions( session ); - if ( getAttributeMapping().getIndexDescriptor() != null && !indexContainsFormula ) { - final Object index = collection.getIndex( entry, entryPosition, getAttributeMapping().getCollectionDescriptor() ); + if ( attributeMapping.getIndexDescriptor() != null && !indexContainsFormula ) { + final Object index = + collection.getIndex( entry, entryPosition, + attributeMapping.getCollectionDescriptor() ); final Object adjustedIndex = incrementIndexByBase( index ); - getAttributeMapping().getIndexDescriptor().decompose( + attributeMapping.getIndexDescriptor().decompose( adjustedIndex, 0, jdbcValueBindings, @@ -558,17 +530,15 @@ private void applyUpdateRowRestrictions( ); } else { - final Object snapshotElement = collection.getSnapshotElement( entry, entryPosition ); - getAttributeMapping().getElementDescriptor().decompose( - snapshotElement, + attributeMapping.getElementDescriptor().decompose( + collection.getSnapshotElement( entry, entryPosition ), 0, jdbcValueBindings, null, (valueIndex, bindings, noop, jdbcValue, jdbcValueMapping) -> { - if ( jdbcValueMapping.isNullable() || jdbcValueMapping.isFormula() ) { - return; + if ( !jdbcValueMapping.isNullable() && !jdbcValueMapping.isFormula() ) { + bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.RESTRICT ); } - bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.RESTRICT ); }, session ); @@ -581,90 +551,77 @@ private void applyUpdateRowRestrictions( // Delete handling private JdbcMutationOperation generateDeleteRowOperation(MutatingTableReference tableReference) { - final RestrictedTableMutation sqlAst = generateDeleteRowAst( tableReference ); - - final SqlAstTranslator translator = getFactory().getJdbcServices() - .getDialect() - .getSqlAstTranslatorFactory() - .buildModelMutationTranslator( sqlAst, getFactory() ); - - return translator.translate( null, MutationQueryOptions.INSTANCE ); + return getSqlAstTranslatorFactory() + .buildModelMutationTranslator( generateDeleteRowAst( tableReference ), getFactory() ) + .translate( null, MutationQueryOptions.INSTANCE ); } private RestrictedTableMutation generateDeleteRowAst(MutatingTableReference tableReference) { - final PluralAttributeMapping pluralAttribute = getAttributeMapping(); + final var pluralAttribute = getAttributeMapping(); assert pluralAttribute != null; - - final SoftDeleteMapping softDeleteMapping = pluralAttribute.getSoftDeleteMapping(); + final var softDeleteMapping = pluralAttribute.getSoftDeleteMapping(); if ( softDeleteMapping != null ) { return generateSoftDeleteRowsAst( tableReference ); } - - final ForeignKeyDescriptor fkDescriptor = pluralAttribute.getKeyDescriptor(); - assert fkDescriptor != null; - - // note that custom sql delete row details are handled by CollectionRowDeleteBuilder - final CollectionRowDeleteBuilder deleteBuilder = new CollectionRowDeleteBuilder( - this, - tableReference, - getFactory(), - sqlWhereString - ); - - if ( pluralAttribute.getIdentifierDescriptor() != null ) { - deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getIdentifierDescriptor() ); - } else { - deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getKeyDescriptor().getKeyPart() ); - - if ( hasIndex() && !indexContainsFormula ) { - assert pluralAttribute.getIndexDescriptor() != null; - deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getIndexDescriptor() ); + final var foreignKeyDescriptor = pluralAttribute.getKeyDescriptor(); + assert foreignKeyDescriptor != null; + // note that custom sql delete row details are handled by CollectionRowDeleteBuilder + final var deleteBuilder = new CollectionRowDeleteBuilder( + this, + tableReference, + getFactory(), + sqlWhereString + ); + if ( pluralAttribute.getIdentifierDescriptor() != null ) { + deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getIdentifierDescriptor() ); } else { - deleteBuilder.addKeyRestrictions( pluralAttribute.getElementDescriptor() ); + deleteBuilder.addKeyRestrictionsLeniently( foreignKeyDescriptor.getKeyPart() ); + if ( hasIndex() && !indexContainsFormula ) { + assert pluralAttribute.getIndexDescriptor() != null; + deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getIndexDescriptor() ); + } + else { + deleteBuilder.addKeyRestrictions( pluralAttribute.getElementDescriptor() ); + } } + //noinspection unchecked,rawtypes + return (RestrictedTableMutation) deleteBuilder.buildMutation(); } - - //noinspection unchecked,rawtypes - return (RestrictedTableMutation) deleteBuilder.buildMutation(); } protected RestrictedTableMutation generateSoftDeleteRowsAst(MutatingTableReference tableReference) { - final SoftDeleteMapping softDeleteMapping = getAttributeMapping().getSoftDeleteMapping(); + final var attributeMapping = getAttributeMapping(); + final var softDeleteMapping = attributeMapping.getSoftDeleteMapping(); assert softDeleteMapping != null; - - final ForeignKeyDescriptor fkDescriptor = getAttributeMapping().getKeyDescriptor(); - assert fkDescriptor != null; - + final var foreignKeyDescriptor = attributeMapping.getKeyDescriptor(); + assert foreignKeyDescriptor != null; final TableUpdateBuilderStandard updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory(), sqlWhereString ); - - if ( getAttributeMapping().getIdentifierDescriptor() != null ) { - updateBuilder.addKeyRestrictionsLeniently( getAttributeMapping().getIdentifierDescriptor() ); + if ( attributeMapping.getIdentifierDescriptor() != null ) { + updateBuilder.addKeyRestrictionsLeniently( attributeMapping.getIdentifierDescriptor() ); } else { - updateBuilder.addKeyRestrictionsLeniently( getAttributeMapping().getKeyDescriptor().getKeyPart() ); - + updateBuilder.addKeyRestrictionsLeniently( foreignKeyDescriptor.getKeyPart() ); if ( hasIndex() && !indexContainsFormula ) { - assert getAttributeMapping().getIndexDescriptor() != null; - updateBuilder.addKeyRestrictionsLeniently( getAttributeMapping().getIndexDescriptor() ); + assert attributeMapping.getIndexDescriptor() != null; + updateBuilder.addKeyRestrictionsLeniently( attributeMapping.getIndexDescriptor() ); } else { - updateBuilder.addKeyRestrictions( getAttributeMapping().getElementDescriptor() ); + updateBuilder.addKeyRestrictions( attributeMapping.getElementDescriptor() ); } } - final ColumnReference softDeleteColumnReference = new ColumnReference( tableReference, softDeleteMapping ); + final var softDeleteColumnReference = new ColumnReference( tableReference, softDeleteMapping ); // apply the assignment updateBuilder.addValueColumn( softDeleteMapping.createDeletedValueBinding( softDeleteColumnReference ) ); // apply the restriction updateBuilder.addNonKeyRestriction( softDeleteMapping.createNonDeletedValueBinding( softDeleteColumnReference ) ); - return updateBuilder.buildMutation(); } @@ -675,8 +632,7 @@ private void applyDeleteRowRestrictions( int rowPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - final PluralAttributeMapping attributeMapping = getAttributeMapping(); - + final var attributeMapping = getAttributeMapping(); if ( attributeMapping.getIdentifierDescriptor() != null ) { attributeMapping.getIdentifierDescriptor().decompose( rowValue, @@ -688,7 +644,7 @@ private void applyDeleteRowRestrictions( ); } else { - getAttributeMapping().getKeyDescriptor().getKeyPart().decompose( + attributeMapping.getKeyDescriptor().getKeyPart().decompose( keyValue, 0, jdbcValueBindings, @@ -696,7 +652,6 @@ private void applyDeleteRowRestrictions( RowMutationOperations.DEFAULT_RESTRICTOR, session ); - if ( hasPhysicalIndexColumn() ) { attributeMapping.getIndexDescriptor().decompose( incrementIndexByBase( rowValue ), @@ -714,10 +669,9 @@ private void applyDeleteRowRestrictions( jdbcValueBindings, null, (valueIndex, bindings, noop, jdbcValue, jdbcValueMapping) -> { - if ( jdbcValueMapping.isNullable() || jdbcValueMapping.isFormula() ) { - return; + if ( !jdbcValueMapping.isNullable() && !jdbcValueMapping.isFormula() ) { + bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.RESTRICT ); } - bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.RESTRICT ); }, session ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java index 87210cbb1c6c..bcf5d2c82439 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java @@ -16,7 +16,6 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; -import org.hibernate.engine.jdbc.mutation.MutationExecutor; import org.hibernate.engine.jdbc.mutation.ParameterUsage; import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; @@ -24,11 +23,6 @@ import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.jdbc.Expectation; import org.hibernate.mapping.Collection; -import org.hibernate.metamodel.mapping.CollectionPart; -import org.hibernate.metamodel.mapping.EntityIdentifierMapping; -import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; -import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.metamodel.mapping.internal.OneToManyCollectionPart; @@ -51,17 +45,13 @@ import org.hibernate.persister.collection.mutation.UpdateRowsCoordinatorNoOp; import org.hibernate.persister.collection.mutation.UpdateRowsCoordinatorOneToMany; import org.hibernate.persister.collection.mutation.UpdateRowsCoordinatorTablePerSubclass; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.UnionSubclassEntityPersister; -import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.predicate.Predicate; -import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.ColumnValueBinding; -import org.hibernate.sql.model.ast.ColumnValueParameter; import org.hibernate.sql.model.ast.ColumnValueParameterList; import org.hibernate.sql.model.ast.ColumnWriteFragment; import org.hibernate.sql.model.ast.MutatingTableReference; @@ -104,15 +94,17 @@ public class OneToManyPersister extends AbstractCollectionPersister { public OneToManyPersister( Collection collectionBinding, CollectionDataAccess cacheAccessStrategy, - RuntimeModelCreationContext creationContext) throws MappingException, CacheException { + RuntimeModelCreationContext creationContext) + throws MappingException, CacheException { super( collectionBinding, cacheAccessStrategy, creationContext ); keyIsNullable = collectionBinding.getKey().isNullable(); - doWriteEvenWhenInverse = isInverse - && hasIndex() - && !indexContainsFormula - && isAnyTrue( indexColumnIsSettable ) - && !getElementPersisterInternal().managesColumns( indexColumnNames ); + doWriteEvenWhenInverse = + isInverse + && hasIndex() + && !indexContainsFormula + && isAnyTrue( indexColumnIsSettable ) + && !getElementPersisterInternal().managesColumns( indexColumnNames ); rowMutationOperations = buildRowMutationOperations(); @@ -120,7 +112,7 @@ && isAnyTrue( indexColumnIsSettable ) updateRowsCoordinator = buildUpdateCoordinator(); deleteRowsCoordinator = buildDeleteCoordinator(); removeCoordinator = buildDeleteAllCoordinator(); - mutationExecutorService = creationContext.getServiceRegistry().getService( MutationExecutorService.class ); + mutationExecutorService = creationContext.getServiceRegistry().getService( MutationExecutorService.class ); } @Override @@ -198,18 +190,18 @@ private void writeIndex( // users complain. if ( doWriteEvenWhenInverse && entries.hasNext() ) { - final JdbcMutationOperation updateRowOperation = rowMutationOperations.getUpdateRowOperation(); - final RowMutationOperations.Values updateRowValues = rowMutationOperations.getUpdateRowValues(); - final RowMutationOperations.Restrictions updateRowRestrictions = rowMutationOperations.getUpdateRowRestrictions(); + final var updateRowOperation = rowMutationOperations.getUpdateRowOperation(); + final var updateRowValues = rowMutationOperations.getUpdateRowValues(); + final var updateRowRestrictions = rowMutationOperations.getUpdateRowRestrictions(); assert areAllNonNull( updateRowOperation, updateRowValues, updateRowRestrictions ); - final MutationExecutor mutationExecutor = mutationExecutorService.createExecutor( + final var mutationExecutor = mutationExecutorService.createExecutor( () -> new BasicBatchKey( getNavigableRole() + "#INDEX" ), MutationOperationGroupFactory.singleOperation( MutationType.UPDATE, this, updateRowOperation ), session ); - final JdbcValueBindings jdbcValueBindings = mutationExecutor.getJdbcValueBindings(); + final var jdbcValueBindings = mutationExecutor.getJdbcValueBindings(); try { int nextIndex = ( resetIndex ? 0 : getSize( key, session ) ) + Math.max( getAttributeMapping().getIndexMetadata().getListIndexBase(), 0 ); @@ -264,7 +256,6 @@ protected void applyWhereFragments( TableGroup tableGroup, SqlAstCreationState astCreationState) { super.applyWhereFragments( predicateConsumer, alias, tableGroup, astCreationState ); - if ( !astCreationState.supportsEntityNameUsage() ) { // We only need to apply discriminator for loads, since queries with joined // inheritance subtypes are already filtered by the entity name usage logic @@ -290,26 +281,24 @@ public FilterAliasGenerator getFilterAliasGenerator(TableGroup rootTableGroup) { @Override public RestrictedTableMutation generateDeleteAllAst(MutatingTableReference tableReference) { - assert getAttributeMapping() != null; + final var attributeMapping = getAttributeMapping(); + assert attributeMapping != null; - final ForeignKeyDescriptor fkDescriptor = getAttributeMapping().getKeyDescriptor(); - assert fkDescriptor != null; + final var foreignKeyDescriptor = attributeMapping.getKeyDescriptor(); + assert foreignKeyDescriptor != null; - final int keyColumnCount = fkDescriptor.getJdbcTypeCount(); + final int keyColumnCount = foreignKeyDescriptor.getJdbcTypeCount(); final int valuesCount = hasIndex() ? keyColumnCount + indexColumnNames.length : keyColumnCount; - final ColumnValueParameterList parameterBinders = new ColumnValueParameterList( - tableReference, - ParameterUsage.RESTRICT, - keyColumnCount - ); + final var parameterBinders = + new ColumnValueParameterList( tableReference, ParameterUsage.RESTRICT, keyColumnCount ); final List keyRestrictionBindings = arrayList( keyColumnCount ); final List valueBindings = arrayList( valuesCount ); - fkDescriptor.getKeyPart().forEachSelectable( parameterBinders ); - for ( ColumnValueParameter columnValueParameter : parameterBinders ) { - final ColumnReference columnReference = columnValueParameter.getColumnReference(); + foreignKeyDescriptor.getKeyPart().forEachSelectable( parameterBinders ); + for ( var columnValueParameter : parameterBinders ) { + final var columnReference = columnValueParameter.getColumnReference(); keyRestrictionBindings.add( new ColumnValueBinding( columnReference, @@ -329,14 +318,15 @@ public RestrictedTableMutation generateDeleteAllAst(Mutat } if ( hasIndex() && !indexContainsFormula ) { - getAttributeMapping().getIndexDescriptor().forEachSelectable( (selectionIndex, selectableMapping) -> { - if ( ! selectableMapping.isUpdateable() ) { - return; + attributeMapping.getIndexDescriptor().forEachSelectable( (selectionIndex, selectableMapping) -> { + if ( selectableMapping.isUpdateable() ) { + valueBindings.add( + new ColumnValueBinding( + new ColumnReference( tableReference, selectableMapping ), + new ColumnWriteFragment( "null", selectableMapping.getJdbcMapping() ) + ) + ); } - valueBindings.add( - new ColumnValueBinding( new ColumnReference( tableReference, selectableMapping ), - new ColumnWriteFragment( "null", selectableMapping.getJdbcMapping() ) - ) ); } ); } @@ -403,7 +393,6 @@ private RowMutationOperations buildRowMutationOperations() { ); } - private InsertRowsCoordinator buildInsertCoordinator() { if ( isInverse() || !isRowInsertEnabled() ) { // if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) { @@ -412,8 +401,8 @@ private InsertRowsCoordinator buildInsertCoordinator() { return new InsertRowsCoordinatorNoOp( this ); } else { - final ServiceRegistryImplementor serviceRegistry = getFactory().getServiceRegistry(); - final EntityPersister elementPersister = getElementPersisterInternal(); + final var serviceRegistry = getFactory().getServiceRegistry(); + final var elementPersister = getElementPersisterInternal(); return elementPersister != null && elementPersister.hasSubclasses() && elementPersister instanceof UnionSubclassEntityPersister ? new InsertRowsCoordinatorTablePerSubclass( this, rowMutationOperations, serviceRegistry ) @@ -429,11 +418,12 @@ private UpdateRowsCoordinator buildUpdateCoordinator() { return new UpdateRowsCoordinatorNoOp( this ); } else { - final EntityPersister elementPersister = getElementPersisterInternal(); + final var elementPersister = getElementPersisterInternal(); + final var factory = getFactory(); return elementPersister != null && elementPersister.hasSubclasses() - && elementPersister instanceof UnionSubclassEntityPersister - ? new UpdateRowsCoordinatorTablePerSubclass( this, rowMutationOperations, getFactory() ) - : new UpdateRowsCoordinatorOneToMany( this, rowMutationOperations, getFactory() ); + && elementPersister instanceof UnionSubclassEntityPersister + ? new UpdateRowsCoordinatorTablePerSubclass( this, rowMutationOperations, factory ) + : new UpdateRowsCoordinatorOneToMany( this, rowMutationOperations, factory ); } } @@ -445,10 +435,10 @@ private DeleteRowsCoordinator buildDeleteCoordinator() { return new DeleteRowsCoordinatorNoOp( this ); } else { - final EntityPersister elementPersister = getElementPersisterInternal(); - final ServiceRegistryImplementor serviceRegistry = getFactory().getServiceRegistry(); + final var elementPersister = getElementPersisterInternal(); + final var serviceRegistry = getFactory().getServiceRegistry(); return elementPersister != null && elementPersister.hasSubclasses() - && elementPersister instanceof UnionSubclassEntityPersister + && elementPersister instanceof UnionSubclassEntityPersister // never delete by index for one-to-many ? new DeleteRowsCoordinatorTablePerSubclass( this, rowMutationOperations, false, serviceRegistry ) : new DeleteRowsCoordinatorStandard( this, rowMutationOperations, false, serviceRegistry ); @@ -463,33 +453,33 @@ private RemoveCoordinator buildDeleteAllCoordinator() { return new RemoveCoordinatorNoOp( this ); } else { - final ServiceRegistryImplementor serviceRegistry = getFactory().getServiceRegistry(); - final EntityPersister elementPersister = getElementPersisterInternal(); + final var serviceRegistry = getFactory().getServiceRegistry(); + final var elementPersister = getElementPersisterInternal(); return elementPersister != null && elementPersister.hasSubclasses() - && elementPersister instanceof UnionSubclassEntityPersister + && elementPersister instanceof UnionSubclassEntityPersister ? new RemoveCoordinatorTablePerSubclass( this, this::buildDeleteAllOperation, serviceRegistry ) : new RemoveCoordinatorStandard( this, this::buildDeleteAllOperation, serviceRegistry ); } } private JdbcMutationOperation generateDeleteRowOperation(MutatingTableReference tableReference) { - return getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory() + return getSqlAstTranslatorFactory() .buildModelMutationTranslator( generateDeleteRowAst( tableReference ), getFactory() ) .translate( null, MutationQueryOptions.INSTANCE ); } public RestrictedTableMutation generateDeleteRowAst(MutatingTableReference tableReference) { - // note that custom sql delete row details are handled by CollectionRowUpdateBuilder - final CollectionRowDeleteByUpdateSetNullBuilder updateBuilder = + // note that custom SQL delete row details are handled by CollectionRowUpdateBuilder + final var updateBuilder = new CollectionRowDeleteByUpdateSetNullBuilder<>( this, tableReference, getFactory(), sqlWhereString ); // for each key column - // 1) set the value to null // 2) restrict based on key value - final ForeignKeyDescriptor keyDescriptor = getAttributeMapping().getKeyDescriptor(); - final int keyTypeCount = keyDescriptor.getJdbcTypeCount(); + final var foreignKeyDescriptor = getAttributeMapping().getKeyDescriptor(); + final int keyTypeCount = foreignKeyDescriptor.getJdbcTypeCount(); for ( int i = 0; i < keyTypeCount; i++ ) { - final SelectableMapping selectable = keyDescriptor.getSelectable( i ); + final SelectableMapping selectable = foreignKeyDescriptor.getSelectable( i ); if ( !selectable.isFormula() ) { if ( selectable.isUpdateable() ) { // set null @@ -507,11 +497,11 @@ public RestrictedTableMutation generateDeleteRowAst(Mutat // set the value for each index column to null if ( hasIndex() && !indexContainsFormula ) { - final CollectionPart indexDescriptor = getAttributeMapping().getIndexDescriptor(); + final var indexDescriptor = getAttributeMapping().getIndexDescriptor(); assert indexDescriptor != null; final int indexTypeCount = indexDescriptor.getJdbcTypeCount(); for ( int i = 0; i < indexTypeCount; i++ ) { - final SelectableMapping selectable = indexDescriptor.getSelectable( i ); + final var selectable = indexDescriptor.getSelectable( i ); if ( selectable.isUpdateable() ) { updateBuilder.addValueColumn( selectable.getSelectionExpression(), @@ -525,8 +515,8 @@ public RestrictedTableMutation generateDeleteRowAst(Mutat // for one-to-many, we know the element is an entity and need to restrict the update // based on the element's id - final EntityCollectionPart entityPart = (EntityCollectionPart) getAttributeMapping().getElementDescriptor(); - final EntityIdentifierMapping entityId = entityPart.getAssociatedEntityMappingType().getIdentifierMapping(); + final var entityPart = (EntityCollectionPart) getAttributeMapping().getElementDescriptor(); + final var entityId = entityPart.getAssociatedEntityMappingType().getIdentifierMapping(); updateBuilder.addKeyRestrictionsLeniently( entityId ); //noinspection unchecked,rawtypes @@ -540,7 +530,7 @@ private void applyDeleteRowRestrictions( int rowPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - final PluralAttributeMapping pluralAttribute = getAttributeMapping(); + final var pluralAttribute = getAttributeMapping(); pluralAttribute.getKeyDescriptor().decompose( keyValue, 0, @@ -561,25 +551,22 @@ private void applyDeleteRowRestrictions( private JdbcMutationOperation generateInsertRowOperation(MutatingTableReference tableReference) { - // NOTE : `TableUpdateBuilderStandard` and `TableUpdate` already handle custom-sql - final TableUpdate tableUpdate = buildTableUpdate( tableReference ); - return tableUpdate.createMutationOperation( null, getFactory() ); + // NOTE: `TableUpdateBuilderStandard` and `TableUpdate` already handle custom-sql + return buildTableUpdate( tableReference ) + .createMutationOperation( null, getFactory() ); } private TableUpdate buildTableUpdate(MutatingTableReference tableReference) { final TableUpdateBuilderStandard updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory(), sqlWhereString ); - - final PluralAttributeMapping attributeMapping = getAttributeMapping(); + final var attributeMapping = getAttributeMapping(); attributeMapping.getKeyDescriptor().getKeyPart().forEachSelectable( updateBuilder ); - - final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor(); + final var indexDescriptor = attributeMapping.getIndexDescriptor(); if ( indexDescriptor != null ) { indexDescriptor.forEachUpdatable( updateBuilder ); } - - final EntityCollectionPart elementDescriptor = (EntityCollectionPart) attributeMapping.getElementDescriptor(); - final EntityMappingType elementType = elementDescriptor.getAssociatedEntityMappingType(); + final var elementDescriptor = (EntityCollectionPart) attributeMapping.getElementDescriptor(); + final var elementType = elementDescriptor.getAssociatedEntityMappingType(); assert elementType.containsTableReference( tableReference.getTableName() ); updateBuilder.addKeyRestrictionsLeniently( elementType.getIdentifierMapping() ); return (TableUpdate) updateBuilder.buildMutation(); @@ -592,8 +579,7 @@ private void applyInsertRowValues( int rowPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - final PluralAttributeMapping attributeMapping = getAttributeMapping(); - + final var attributeMapping = getAttributeMapping(); attributeMapping.getKeyDescriptor().getKeyPart().decompose( keyValue, 0, @@ -602,9 +588,7 @@ private void applyInsertRowValues( RowMutationOperations.DEFAULT_VALUE_SETTER, session ); - - final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor(); - + final var indexDescriptor = attributeMapping.getIndexDescriptor(); if ( indexDescriptor != null ) { indexDescriptor.decompose( incrementIndexByBase( collection.getIndex( rowValue, rowPosition, this ) ), @@ -612,18 +596,17 @@ private void applyInsertRowValues( jdbcValueBindings, null, (valueIndex, bindings, noop, value, jdbcValueMapping) -> { - if ( !jdbcValueMapping.isUpdateable() ) { - return; + if ( jdbcValueMapping.isUpdateable() ) { + bindings.bindValue( value, jdbcValueMapping, ParameterUsage.SET ); } - bindings.bindValue( value, jdbcValueMapping, ParameterUsage.SET ); }, session ); } final Object elementValue = collection.getElement( rowValue ); - final EntityCollectionPart elementDescriptor = (EntityCollectionPart) attributeMapping.getElementDescriptor(); - final EntityIdentifierMapping identifierMapping = elementDescriptor.getAssociatedEntityMappingType().getIdentifierMapping(); + final var elementDescriptor = (EntityCollectionPart) attributeMapping.getElementDescriptor(); + final var identifierMapping = elementDescriptor.getAssociatedEntityMappingType().getIdentifierMapping(); identifierMapping.decompose( identifierMapping.getIdentifier( elementValue ), 0, @@ -636,25 +619,22 @@ private void applyInsertRowValues( private JdbcMutationOperation generateWriteIndexOperation(MutatingTableReference tableReference) { - // note that custom sql update details are handled by TableUpdateBuilderStandard + // note that custom SQL update details are handled by TableUpdateBuilderStandard final TableUpdateBuilderStandard updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory(), sqlWhereString ); - - final OneToManyCollectionPart elementDescriptor = (OneToManyCollectionPart) getAttributeMapping().getElementDescriptor(); + final var attributeMapping = getAttributeMapping(); + final var elementDescriptor = (OneToManyCollectionPart) attributeMapping.getElementDescriptor(); updateBuilder.addKeyRestrictionsLeniently( elementDescriptor.getAssociatedEntityMappingType().getIdentifierMapping() ); - // if the collection has an identifier, add its column as well - if ( getAttributeMapping().getIdentifierDescriptor() != null ) { - updateBuilder.addKeyRestrictionsLeniently( getAttributeMapping().getIdentifierDescriptor() ); + if ( attributeMapping.getIdentifierDescriptor() != null ) { + updateBuilder.addKeyRestrictionsLeniently( attributeMapping.getIdentifierDescriptor() ); } - // for each index column: // * add a restriction based on the previous value // * add an assignment for the new value - getAttributeMapping().getIndexDescriptor().forEachUpdatable( updateBuilder ); - - final RestrictedTableMutation tableUpdate = updateBuilder.buildMutation(); - return tableUpdate.createMutationOperation( null, getFactory() ); + attributeMapping.getIndexDescriptor().forEachUpdatable( updateBuilder ); + return updateBuilder.buildMutation() + .createMutationOperation( null, getFactory() ); } private void applyWriteIndexValues( @@ -686,12 +666,12 @@ private void applyWriteIndexRestrictions( int entryPosition, SharedSessionContractImplementor session, JdbcValueBindings jdbcValueBindings) { - final OneToManyCollectionPart elementDescriptor = (OneToManyCollectionPart) getAttributeMapping().getElementDescriptor(); - final EntityMappingType associatedType = elementDescriptor.getAssociatedEntityMappingType(); + final var attributeMapping = getAttributeMapping(); + final var elementDescriptor = (OneToManyCollectionPart) attributeMapping.getElementDescriptor(); + final var associatedType = elementDescriptor.getAssociatedEntityMappingType(); final Object element = collection.getElement( entry ); - final Object elementIdentifier = associatedType.getIdentifierMapping().getIdentifier( element ); associatedType.getIdentifierMapping().decompose( - elementIdentifier, + associatedType.getIdentifierMapping().getIdentifier( element ), 0, jdbcValueBindings, null, @@ -699,10 +679,9 @@ private void applyWriteIndexRestrictions( session ); - if ( getAttributeMapping().getIdentifierDescriptor() != null ) { - final Object identifier = collection.getIdentifier( entry, entryPosition ); - getAttributeMapping().getIdentifierDescriptor().decompose( - identifier, + if ( attributeMapping.getIdentifierDescriptor() != null ) { + attributeMapping.getIdentifierDescriptor().decompose( + collection.getIdentifier( entry, entryPosition ), 0, jdbcValueBindings, null, 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 059b0f09143f..bdf1a9aef57c 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 @@ -25,12 +25,9 @@ import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer; -import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeDescriptor; -import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor; -import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.bytecode.spi.ReflectionOptimizer; import org.hibernate.cache.spi.access.EntityDataAccess; @@ -46,20 +43,16 @@ import org.hibernate.dialect.lock.LockingStrategy; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.OptimisticLockStyle; -import org.hibernate.engine.internal.CacheHelper; import org.hibernate.engine.internal.ImmutableEntityEntryFactory; import org.hibernate.engine.internal.MutableEntityEntryFactory; -import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.profile.internal.FetchProfileAffectee; import org.hibernate.engine.spi.CachedNaturalIdValueSource; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntryFactory; -import org.hibernate.engine.spi.EntityHolder; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.NaturalIdResolutions; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -74,20 +67,15 @@ import org.hibernate.generator.internal.VersionGeneration; import org.hibernate.generator.values.GeneratedValues; import org.hibernate.generator.values.GeneratedValuesMutationDelegate; -import org.hibernate.generator.values.internal.GeneratedValuesHelper; -import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.id.BulkInsertionCapableIdentifierGenerator; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.OptimizableGenerator; -import org.hibernate.id.enhanced.Optimizer; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.FilterHelper; import org.hibernate.internal.util.IndexedConsumer; import org.hibernate.internal.util.MarkerObject; import org.hibernate.internal.util.StringHelper; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.LockModeEnumMap; import org.hibernate.jdbc.Expectation; import org.hibernate.loader.ast.internal.EntityConcreteTypeLoader; @@ -112,13 +100,9 @@ import org.hibernate.mapping.Component; import org.hibernate.mapping.DependantValue; import org.hibernate.mapping.Formula; -import org.hibernate.mapping.Join; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; -import org.hibernate.mapping.Selectable; -import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; -import org.hibernate.mapping.Value; import org.hibernate.metamodel.UnsupportedMappingException; import org.hibernate.metamodel.mapping.Association; import org.hibernate.metamodel.mapping.AttributeMapping; @@ -134,7 +118,7 @@ import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.ManagedMappingType; -import org.hibernate.metamodel.mapping.internal.MappingModelHelper; +import org.hibernate.metamodel.mapping.MappingType; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; @@ -161,7 +145,6 @@ import org.hibernate.metamodel.mapping.internal.SimpleNaturalIdMapping; import org.hibernate.metamodel.mapping.internal.UnifiedAnyDiscriminatorConverter; import org.hibernate.metamodel.model.domain.NavigableRole; -import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.metamodel.spi.EntityRepresentationStrategy; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; @@ -189,7 +172,6 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategyProvider; -import org.hibernate.service.ServiceRegistry; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.Alias; import org.hibernate.sql.InFragment; @@ -218,22 +200,17 @@ import org.hibernate.sql.ast.tree.predicate.NullnessPredicate; import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.ast.tree.select.QuerySpec; -import org.hibernate.sql.ast.tree.select.SelectClause; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcParametersList; -import org.hibernate.sql.model.MutationOperation; -import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.ast.ColumnValueBinding; import org.hibernate.sql.model.ast.MutatingTableReference; import org.hibernate.sql.model.ast.builder.MutationGroupBuilder; import org.hibernate.sql.model.ast.builder.TableInsertBuilder; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; -import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; -import org.hibernate.sql.results.graph.FetchableContainer; import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; import org.hibernate.sql.results.internal.SqlSelectionImpl; @@ -253,8 +230,6 @@ import org.hibernate.type.spi.TypeConfiguration; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; @@ -280,18 +255,23 @@ import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableList; import static org.hibernate.boot.model.internal.SoftDeleteHelper.resolveSoftDeleteMapping; +import static org.hibernate.engine.internal.CacheHelper.fromSharedCache; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.processIfPersistentAttributeInterceptable; import static org.hibernate.generator.EventType.FORCE_INCREMENT; import static org.hibernate.generator.EventType.INSERT; import static org.hibernate.generator.EventType.UPDATE; +import static org.hibernate.generator.values.internal.GeneratedValuesHelper.getGeneratedValuesDelegate; import static org.hibernate.internal.util.ReflectHelper.isAbstractClass; import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.qualify; import static org.hibernate.internal.util.StringHelper.qualifyConditionally; +import static org.hibernate.internal.util.StringHelper.root; import static org.hibernate.internal.util.StringHelper.unqualify; +import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_INT_ARRAY; import static org.hibernate.internal.util.collections.ArrayHelper.contains; +import static org.hibernate.internal.util.collections.ArrayHelper.indexOf; import static org.hibernate.internal.util.collections.ArrayHelper.isAllTrue; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray; @@ -304,6 +284,12 @@ import static org.hibernate.internal.util.collections.CollectionHelper.toSmallList; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.supportsSqlArrayType; import static org.hibernate.metamodel.RepresentationMode.POJO; +import static org.hibernate.metamodel.mapping.internal.GeneratedValuesProcessor.getGeneratedAttributes; +import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildBasicAttributeMapping; +import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildEncapsulatedCompositeIdentifierMapping; +import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildNonEncapsulatedCompositeIdentifierMapping; +import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.resolveAggregateColumnBasicType; +import static org.hibernate.metamodel.mapping.internal.MappingModelHelper.isCompatibleModelPart; import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR; import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR; import static org.hibernate.pretty.MessageHelper.infoString; @@ -318,6 +304,7 @@ @Internal @SuppressWarnings("deprecation") public abstract class AbstractEntityPersister + extends EntityMetamodel implements EntityPersister, InFlightEntityMappingType, EntityMutationTarget, LazyPropertyInitializer, FetchProfileAffectee, Joinable { @@ -466,8 +453,10 @@ public AbstractEntityPersister( final PersistentClass persistentClass, final EntityDataAccess cacheAccessStrategy, final NaturalIdDataAccess naturalIdRegionAccessStrategy, - final RuntimeModelCreationContext creationContext) throws HibernateException { - this.jpaEntityName = persistentClass.getJpaEntityName(); + final RuntimeModelCreationContext creationContext) + throws HibernateException { + super( persistentClass, creationContext ); + jpaEntityName = persistentClass.getJpaEntityName(); //set it here, but don't call it, since it's still uninitialized! factory = creationContext.getSessionFactory(); @@ -476,9 +465,9 @@ public AbstractEntityPersister( navigableRole = new NavigableRole( persistentClass.getEntityName() ); - final SessionFactoryOptions sessionFactoryOptions = creationContext.getSessionFactoryOptions(); + final var factoryOptions = creationContext.getSessionFactoryOptions(); - if ( sessionFactoryOptions.isSecondLevelCacheEnabled() ) { + if ( factoryOptions.isSecondLevelCacheEnabled() ) { this.cacheAccessStrategy = cacheAccessStrategy; this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy; canWriteToCache = determineCanWriteToCache( persistentClass, cacheAccessStrategy ); @@ -493,20 +482,17 @@ public AbstractEntityPersister( isLazyPropertiesCacheable = true; } - entityMetamodel = creationContext.createEntityMetamodel( persistentClass, this ); - - entityEntryFactory = entityMetamodel.isMutable() - ? MutableEntityEntryFactory.INSTANCE - : ImmutableEntityEntryFactory.INSTANCE; + entityEntryFactory = + isMutable() + ? MutableEntityEntryFactory.INSTANCE + : ImmutableEntityEntryFactory.INSTANCE; // Handle any filters applied to the class level if ( isNotEmpty( persistentClass.getFilters() ) ) { filterHelper = new FilterHelper( persistentClass.getFilters(), - getEntityNameByTableNameMap( - persistentClass, - factory.getSqlStringGenerationContext() - ), + getEntityNameByTableNameMap( persistentClass, + factory.getSqlStringGenerationContext() ), factory ); } @@ -523,15 +509,17 @@ public AbstractEntityPersister( assert javaType != null; accessOptimizer = accessOptimizer( representationStrategy ); - concreteProxy = entityMetamodel.isPolymorphic() - && ( getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() || hasProxy() ) - && persistentClass.isConcreteProxy(); + concreteProxy = + isPolymorphic() + && ( getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() || hasProxy() ) + && persistentClass.isConcreteProxy(); - final Dialect dialect = creationContext.getDialect(); + final var dialect = creationContext.getDialect(); - batchSize = persistentClass.getBatchSize() < 0 - ? factory.getSessionFactoryOptions().getDefaultBatchFetchSize() - : persistentClass.getBatchSize(); + batchSize = + persistentClass.getBatchSize() < 0 + ? factoryOptions.getDefaultBatchFetchSize() + : persistentClass.getBatchSize(); hasSubselectLoadableCollections = persistentClass.hasSubselectLoadableCollections(); hasPartitionedSelectionMapping = persistentClass.hasPartitionedSelectionMapping(); hasCollectionNotReferencingPK = persistentClass.hasCollectionNotReferencingPK(); @@ -546,27 +534,29 @@ public AbstractEntityPersister( rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan]; identifierAliases = new String[identifierColumnSpan]; - final String rowId = persistentClass.getRootTable().getRowId(); + final var rootTable = persistentClass.getRootTable(); + final String rowId = rootTable.getRowId(); rowIdName = rowId == null ? null : dialect.rowId( rowId ); queryLoaderName = persistentClass.getLoaderName(); - final TypeConfiguration typeConfiguration = creationContext.getTypeConfiguration(); + final var typeConfiguration = creationContext.getTypeConfiguration(); - final List columns = persistentClass.getIdentifier().getColumns(); + final var columns = persistentClass.getIdentifier().getColumns(); for (int i = 0; i < columns.size(); i++ ) { - final Column column = columns.get(i); + final var column = columns.get(i); rootTableKeyColumnNames[i] = column.getQuotedName( dialect ); rootTableKeyColumnReaders[i] = column.getReadExpr( dialect ); rootTableKeyColumnReaderTemplates[i] = column.getTemplate( dialect, typeConfiguration ); - identifierAliases[i] = column.getAlias( dialect, persistentClass.getRootTable() ); + identifierAliases[i] = column.getAlias( dialect, rootTable ); } // VERSION - versionColumnName = persistentClass.isVersioned() - ? persistentClass.getVersion().getColumns().get(0).getQuotedName( dialect ) - : null; + versionColumnName = + persistentClass.isVersioned() + ? persistentClass.getVersion().getColumns().get(0).getQuotedName( dialect ) + : null; //WHERE STRING @@ -575,24 +565,14 @@ public AbstractEntityPersister( sqlWhereStringTemplate = null; } else { - PersistentClass containingClass = persistentClass; - while ( containingClass.getSuperclass() != null ) { - final PersistentClass superclass = containingClass.getSuperclass(); - if ( !Objects.equals( persistentClass.getWhere(), superclass.getWhere() ) ) { - break; - } - containingClass = superclass; - } - sqlWhereStringTableExpression = determineTableName( containingClass.getTable() ); - sqlWhereStringTemplate = Template.renderWhereStringTemplate( - "(" + persistentClass.getWhere() + ")", - dialect, - typeConfiguration - ); + sqlWhereStringTableExpression = + determineTableName( getCountainingClass( persistentClass ).getTable() ); + sqlWhereStringTemplate = + renderSqlWhereStringTemplate( persistentClass, dialect, typeConfiguration ); } // PROPERTIES - final int hydrateSpan = entityMetamodel.getPropertySpan(); + final int hydrateSpan = getPropertySpan(); propertyColumnAliases = new String[hydrateSpan][]; propertyColumnNames = new String[hydrateSpan][]; propertyColumnFormulaTemplates = new String[hydrateSpan][]; @@ -606,28 +586,27 @@ public AbstractEntityPersister( final ArrayList lazyNumbers = new ArrayList<>(); final ArrayList lazyTypes = new ArrayList<>(); - final List propertyClosure = persistentClass.getPropertyClosure(); + final var propertyClosure = persistentClass.getPropertyClosure(); boolean foundFormula = false; for ( int i = 0; i < propertyClosure.size(); i++ ) { - final Property prop = propertyClosure.get(i); - thisClassProperties.add( prop ); + final var property = propertyClosure.get(i); + thisClassProperties.add( property ); + final var propertyValue = property.getValue(); - final int span = prop.getColumnSpan(); + final int span = property.getColumnSpan(); final String[] colNames = new String[span]; final String[] colAliases = new String[span]; final String[] formulaTemplates = new String[span]; - final List selectables = prop.getSelectables(); + final var selectables = property.getSelectables(); for ( int k = 0; k < selectables.size(); k++ ) { - final Selectable selectable = selectables.get(k); - colAliases[k] = selectable.getAlias( dialect, prop.getValue().getTable() ); - if ( selectable.isFormula() ) { + final var selectable = selectables.get(k); + colAliases[k] = selectable.getAlias( dialect, propertyValue.getTable() ); + if ( selectable instanceof Formula formula ) { foundFormula = true; - final Formula formula = (Formula) selectable; formula.setFormula( substituteBrackets( formula.getFormula() ) ); formulaTemplates[k] = selectable.getTemplate( dialect, typeConfiguration ); } - else { - final Column column = (Column) selectable; + else if ( selectable instanceof Column column ) { colNames[k] = column.getQuotedName( dialect ); } } @@ -636,29 +615,29 @@ public AbstractEntityPersister( propertyColumnAliases[i] = colAliases; final boolean lazy = !EnhancementHelper.includeInBaseFetchGroup( - prop, - entityMetamodel.isInstrumented(), + property, + isInstrumented(), entityName -> { - final PersistentClass entityBinding = creationContext - .getMetadata() - .getEntityBinding( entityName ); + final var entityBinding = + creationContext.getMetadata() + .getEntityBinding( entityName ); assert entityBinding != null; return entityBinding.hasSubclasses(); }, - sessionFactoryOptions.isCollectionsInDefaultFetchGroupEnabled() + factoryOptions.isCollectionsInDefaultFetchGroupEnabled() ); if ( lazy ) { - lazyNames.add( prop.getName() ); + lazyNames.add( property.getName() ); lazyNumbers.add( i ); - lazyTypes.add( prop.getValue().getType() ); + lazyTypes.add( propertyValue.getType() ); } else { - nonLazyPropertyNames.add( prop.getName() ); + nonLazyPropertyNames.add( property.getName() ); } - propertyColumnUpdateable[i] = prop.getValue().getColumnUpdateability(); - propertyColumnInsertable[i] = prop.getValue().getColumnInsertability(); + propertyColumnUpdateable[i] = propertyValue.getColumnUpdateability(); + propertyColumnInsertable[i] = propertyValue.getColumnInsertability(); } hasFormulaProperties = foundFormula; lazyPropertyNames = toStringArray( lazyNames ); @@ -677,59 +656,54 @@ public AbstractEntityPersister( final ArrayList joinedFetchesList = new ArrayList<>(); if ( persistentClass.hasSubclasses() ) { - for ( Selectable selectable : persistentClass.getIdentifier().getSelectables() ) { - if ( !selectable.isFormula() ) { + for ( var selectable : persistentClass.getIdentifier().getSelectables() ) { + if ( selectable instanceof Column column ) { // Identifier columns are always shared between subclasses - sharedColumnNames.add( ( (Column) selectable ).getQuotedName( dialect ) ); + sharedColumnNames.add( column.getQuotedName( dialect ) ); } } } - for ( Property prop : persistentClass.getSubclassPropertyClosure() ) { + for ( var prop : persistentClass.getSubclassPropertyClosure() ) { names.add( prop.getName() ); types.add( prop.getType() ); - final String[] cols = new String[ prop.getColumnSpan() ]; - final String[] readers = new String[ prop.getColumnSpan() ]; - final String[] readerTemplates = new String[ prop.getColumnSpan() ]; - final String[] forms = new String[ prop.getColumnSpan() ]; + final int columnSpan = prop.getColumnSpan(); + final String[] columnNames = new String[columnSpan]; + final String[] readers = new String[columnSpan]; + final String[] readerTemplates = new String[columnSpan]; + final String[] formulaTemplates = new String[columnSpan]; - final List selectables = prop.getSelectables(); + final var selectables = prop.getSelectables(); for ( int i = 0; i < selectables.size(); i++ ) { - final Selectable selectable = selectables.get(i); - if ( selectable.isFormula() ) { - final String template = selectable.getTemplate( dialect, typeConfiguration ); - forms[i] = template; + final var selectable = selectables.get(i); + if ( selectable instanceof Formula ) { + formulaTemplates[i] = selectable.getTemplate( dialect, typeConfiguration ); final String formulaAlias = selectable.getAlias( dialect ); if ( prop.isSelectable() && !formulaAliases.contains( formulaAlias ) ) { formulaAliases.add( formulaAlias ); } } - else { - final Column column = (Column) selectable; - final String colName = column.getQuotedName(dialect); - cols[i] = colName; + else if ( selectable instanceof Column column ) { + final String quotedColumnName = column.getQuotedName( dialect ); + columnNames[i] = quotedColumnName; final String columnAlias = selectable.getAlias( dialect, prop.getValue().getTable() ); if ( prop.isSelectable() && !aliases.contains( columnAlias ) ) { aliases.add( columnAlias ); } - readers[i] = column.getReadExpr( dialect ); - readerTemplates[i] = column.getTemplate( - dialect, - typeConfiguration - ); + readerTemplates[i] = column.getTemplate( dialect, typeConfiguration ); if ( thisClassProperties.contains( prop ) ? persistentClass.hasSubclasses() : persistentClass.isDefinedOnMultipleSubclasses( column ) ) { - sharedColumnNames.add( colName ); + sharedColumnNames.add( quotedColumnName ); } } } - propColumns.add( cols ); + propColumns.add( columnNames ); propColumnReaders.add( readers ); propColumnReaderTemplates.add( readerTemplates ); - templates.add( forms ); + templates.add( formulaTemplates ); joinedFetchesList.add( prop.getValue().getFetchMode() ); } @@ -745,36 +719,34 @@ public AbstractEntityPersister( subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.size()]; int j = 0; - for (FetchMode fetchMode : joinedFetchesList) { + for ( var fetchMode : joinedFetchesList) { subclassPropertyFetchModeClosure[j++] = fetchMode; } - useReferenceCacheEntries = shouldUseReferenceCacheEntries( creationContext.getSessionFactoryOptions() ); - useShallowQueryCacheLayout = shouldUseShallowCacheLayout( - persistentClass.getQueryCacheLayout(), - creationContext.getSessionFactoryOptions() - ); - storeDiscriminatorInShallowQueryCacheLayout = shouldStoreDiscriminatorInShallowQueryCacheLayout( - persistentClass.getQueryCacheLayout(), - creationContext.getSessionFactoryOptions() - ); - cacheEntryHelper = buildCacheEntryHelper( creationContext.getSessionFactoryOptions() ); - invalidateCache = sessionFactoryOptions.isSecondLevelCacheEnabled() - && canWriteToCache - && shouldInvalidateCache( persistentClass, creationContext ); + useReferenceCacheEntries = shouldUseReferenceCacheEntries( factoryOptions ); + final var queryCacheLayout = persistentClass.getQueryCacheLayout(); + useShallowQueryCacheLayout = + shouldUseShallowCacheLayout( queryCacheLayout, factoryOptions ); + storeDiscriminatorInShallowQueryCacheLayout = + shouldStoreDiscriminatorInShallowQueryCacheLayout( queryCacheLayout, factoryOptions ); + cacheEntryHelper = buildCacheEntryHelper( factoryOptions ); + invalidateCache = + factoryOptions.isSecondLevelCacheEnabled() + && canWriteToCache + && shouldInvalidateCache( persistentClass, creationContext ); final List values = new ArrayList<>(); final List sqlValues = new ArrayList<>(); if ( persistentClass.isPolymorphic() && persistentClass.getDiscriminator() != null ) { - if ( !getEntityMetamodel().isAbstract() ) { + if ( !isAbstract() ) { values.add( DiscriminatorHelper.getDiscriminatorValue( persistentClass ) ); sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect ) ); } - final List subclasses = persistentClass.getSubclasses(); + final var subclasses = persistentClass.getSubclasses(); for ( int k = 0; k < subclasses.size(); k++ ) { - final Subclass subclass = subclasses.get( k ); + final var subclass = subclasses.get( k ); //copy/paste from EntityMetamodel: if ( !isAbstract( subclass ) ) { values.add( DiscriminatorHelper.getDiscriminatorValue( subclass ) ); @@ -791,8 +763,29 @@ public AbstractEntityPersister( } } + private static String renderSqlWhereStringTemplate( + PersistentClass persistentClass, Dialect dialect, TypeConfiguration typeConfiguration) { + return Template.renderWhereStringTemplate( + "(" + persistentClass.getWhere() + ")", + dialect, + typeConfiguration + ); + } + + private static PersistentClass getCountainingClass(PersistentClass persistentClass) { + var containingClass = persistentClass; + while ( containingClass.getSuperclass() != null ) { + final var superclass = containingClass.getSuperclass(); + if ( !Objects.equals( persistentClass.getWhere(), superclass.getWhere() ) ) { + break; + } + containingClass = superclass; + } + return containingClass; + } + private NamedQueryMemento getNamedQueryMemento(MetadataImplementor bootModel) { - final NamedQueryMemento memento = + final var memento = factory.getQueryEngine().getNamedObjectRepository() .resolve( factory, bootModel, queryLoaderName ); if ( memento == null ) { @@ -808,7 +801,7 @@ private NamedQueryMemento getNamedQueryMemento(MetadataImplementor bootModel) protected SingleIdEntityLoader buildSingleIdEntityLoader() { if ( hasNamedQueryLoader() ) { // We must resolve the named query on-demand through the boot model because it isn't initialized yet - final NamedQueryMemento memento = getNamedQueryMemento( null ); + final var memento = getNamedQueryMemento( null ); return new SingleIdEntityLoaderProvidedQueryImpl<>( this, memento ); } else { @@ -824,22 +817,19 @@ private SingleIdEntityLoader buildSingleIdEntityLoader( if ( lockOptions != null && needsOneOffLoader( lockOptions ) ) { return new SingleIdEntityLoaderStandardImpl<>( this, loadQueryInfluencers ); } - - if ( loadQueryInfluencers.effectivelyBatchLoadable( this ) ) { + else if ( loadQueryInfluencers.effectivelyBatchLoadable( this ) ) { final int batchSize = loadQueryInfluencers.effectiveBatchSize( this ); return factory.getServiceRegistry().requireService( BatchLoaderFactory.class ) .createEntityBatchLoader( batchSize, this, loadQueryInfluencers ); } - - return new SingleIdEntityLoaderStandardImpl<>( this, loadQueryInfluencers ); + else { + return new SingleIdEntityLoaderStandardImpl<>( this, loadQueryInfluencers ); + } } private boolean needsOneOffLoader(LockOptions lockOptions) { - if ( !lockOptions.getLockMode().isPessimistic() ) { - return false; - } - - return lockOptions.hasNonDefaultOptions(); + return lockOptions.getLockMode().isPessimistic() + && lockOptions.hasNonDefaultOptions(); } public static Map getEntityNameByTableNameMap( @@ -848,16 +838,18 @@ public static Map getEntityNameByTableNameMap( final Map entityNameByTableNameMap = new HashMap<>(); PersistentClass superType = persistentClass.getSuperPersistentClass(); while ( superType != null ) { - entityNameByTableNameMap.put( superType.getTable().getQualifiedName( stringGenerationContext ), superType.getEntityName() ); - for ( Join join : superType.getJoins() ) { - entityNameByTableNameMap.put( join.getTable().getQualifiedName( stringGenerationContext ), superType.getEntityName() ); + final String entityName = superType.getEntityName(); + entityNameByTableNameMap.put( superType.getTable().getQualifiedName( stringGenerationContext ), entityName ); + for ( var join : superType.getJoins() ) { + entityNameByTableNameMap.put( join.getTable().getQualifiedName( stringGenerationContext ), entityName ); } superType = superType.getSuperPersistentClass(); } - for ( PersistentClass subclass : persistentClass.getSubclassClosure() ) { - entityNameByTableNameMap.put( subclass.getTable().getQualifiedName( stringGenerationContext ), subclass.getEntityName() ); - for ( Join join : subclass.getJoins() ) { - entityNameByTableNameMap.put( join.getTable().getQualifiedName( stringGenerationContext ), subclass.getEntityName() ); + for ( var subclass : persistentClass.getSubclassClosure() ) { + final String entityName = subclass.getEntityName(); + entityNameByTableNameMap.put( subclass.getTable().getQualifiedName( stringGenerationContext ), entityName ); + for ( var join : subclass.getJoins() ) { + entityNameByTableNameMap.put( join.getTable().getQualifiedName( stringGenerationContext ), entityName ); } } return entityNameByTableNameMap; @@ -875,7 +867,8 @@ && supportsSqlArrayType( getDialect() ) private String getIdentitySelectString(Dialect dialect) { try { - final int idTypeCode = ((BasicType) getIdentifierType()).getJdbcType().getDdlTypeCode(); + final var identifierType = (BasicType) getIdentifierType(); + final int idTypeCode = identifierType.getJdbcType().getDdlTypeCode(); return dialect.getIdentityColumnSupport() .getIdentitySelectString( getTableName(0), getKeyColumns(0)[0], idTypeCode ); } @@ -898,15 +891,15 @@ private boolean shouldUseReferenceCacheEntries(SessionFactoryOptions options) { return false; } // for now, limit this to just entities that: - else if ( entityMetamodel.isMutable() ) { + else if ( isMutable() ) { // 1) are immutable return false; } else { // 2) have no associations. // Eventually we want to be a little more lenient with associations. - for ( Type type : getSubclassPropertyTypeClosure() ) { - if ( type instanceof AnyType || type instanceof CollectionType || type instanceof EntityType ) { + for ( var type : getSubclassPropertyTypeClosure() ) { + if ( type.isAnyType() || type.isCollectionType() || type.isEntityType() ) { return false; } } @@ -994,7 +987,7 @@ protected boolean isNullableSubclassTable(int j) { @Override public boolean isSubclassEntityName(String entityName) { - return entityMetamodel.getSubclassEntityNames().contains( entityName ); + return getSubclassEntityNames().contains( entityName ); } @Override @@ -1079,7 +1072,7 @@ else if ( isVersioned() ) { // versioned entities return false; } - else if ( entityMetamodel.isDynamicUpdate() ) { + else if ( isDynamicUpdate() ) { // if the unversioned entity has dynamic updates // there is a risk of concurrent updates return true; @@ -1118,7 +1111,7 @@ else if ( persistentClass.isCached() ) { return true; } else { - for ( Subclass subclass : persistentClass.getSubclasses() ) { + for ( var subclass : persistentClass.getSubclasses() ) { if ( subclass.isCached() ) { return true; } @@ -1133,7 +1126,7 @@ protected CacheEntryHelper buildCacheEntryHelper(SessionFactoryOptions options) return NoopCacheEntryHelper.INSTANCE; } else if ( canUseReferenceCacheEntries() ) { - entityMetamodel.setLazy( false ); + setLazy( false ); // todo : do we also need to unset proxy factory? return new ReferenceCacheEntryHelper( this ); } @@ -1179,25 +1172,26 @@ public Iterable uniqueKeyEntries() { return uniqueKeyEntries; } - private static List initUniqueKeyEntries(final AbstractEntityPersister aep) { + private static List initUniqueKeyEntries(final AbstractEntityPersister persister) { final ArrayList uniqueKeys = new ArrayList<>(); - for ( Type propertyType : aep.getPropertyTypes() ) { + for ( var propertyType : persister.getPropertyTypes() ) { if ( propertyType instanceof AssociationType associationType ) { final String ukName = associationType.getLHSPropertyName(); if ( ukName != null ) { - final AttributeMapping attributeMapping = aep.findAttributeMapping( ukName ); + final var attributeMapping = persister.findAttributeMapping( ukName ); if ( attributeMapping != null ) { final int index = attributeMapping.getStateArrayPosition(); - final Type type = aep.getPropertyTypes()[index]; + final Type type = persister.getPropertyTypes()[index]; uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) ); } } else if ( associationType instanceof ManyToOneType manyToOneType - && manyToOneType.isLogicalOneToOne() && manyToOneType.isReferenceToPrimaryKey() ) { - final AttributeMapping attributeMapping = aep.findAttributeMapping( manyToOneType.getPropertyName() ); + && manyToOneType.isLogicalOneToOne() + && manyToOneType.isReferenceToPrimaryKey() ) { + final var attributeMapping = persister.findAttributeMapping( manyToOneType.getPropertyName() ); if ( attributeMapping != null ) { final int index = attributeMapping.getStateArrayPosition(); - final Type type = aep.getPropertyTypes()[index]; + final Type type = persister.getPropertyTypes()[index]; uniqueKeys.add( new UniqueKeyEntry( manyToOneType.getPropertyName(), index, type ) ); } } @@ -1215,12 +1209,11 @@ protected Map getLazyLoadPlanByFetchGroup() { private Map createLazyLoadPlanByFetchGroup(BytecodeEnhancementMetadata metadata) { final Map result = new HashMap<>(); - final LazyAttributesMetadata attributesMetadata = metadata.getLazyAttributesMetadata(); + final var attributesMetadata = metadata.getLazyAttributesMetadata(); for ( String groupName : attributesMetadata.getFetchGroupNames() ) { - final SingleIdArrayLoadPlan loadPlan = - createLazyLoadPlan( attributesMetadata.getFetchGroupAttributeDescriptors( groupName ) ); - if ( loadPlan != null ) { - result.put( groupName, loadPlan ); + final var plan = createLazyLoadPlan( attributesMetadata.getFetchGroupAttributeDescriptors( groupName ) ); + if ( plan != null ) { + result.put( groupName, plan ); } } return result; @@ -1228,7 +1221,7 @@ private Map createLazyLoadPlanByFetchGroup(Byteco private SingleIdArrayLoadPlan createLazyLoadPlan(List fetchGroupAttributeDescriptors) { final List partsToSelect = new ArrayList<>( fetchGroupAttributeDescriptors.size() ); - for ( LazyAttributeDescriptor lazyAttributeDescriptor : fetchGroupAttributeDescriptors ) { + for ( var lazyAttributeDescriptor : fetchGroupAttributeDescriptors ) { // all this only really needs to consider properties // of this class, not its subclasses, but since we // are reusing code used for sequential selects, we @@ -1244,9 +1237,9 @@ private SingleIdArrayLoadPlan createLazyLoanPlan(List partsToSelect) return null; } else { - final LockOptions lockOptions = new LockOptions(); - final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder(); - final SelectStatement select = LoaderSelectBuilder.createSelect( + final var lockOptions = new LockOptions(); + final var jdbcParametersBuilder = JdbcParametersList.newBuilder(); + final var select = LoaderSelectBuilder.createSelect( this, partsToSelect, getIdentifierMapping(), @@ -1289,7 +1282,7 @@ public DomainResult createDomainResult( TableGroup tableGroup, String resultVariable, DomainResultCreationState creationState) { - final EntityResultImpl entityResult = new EntityResultImpl( + final var entityResult = new EntityResultImpl( navigablePath, this, tableGroup, @@ -1345,8 +1338,7 @@ public TableReferenceJoin createTableReferenceJoin( TableReference lhs, SqlAstCreationState creationState) { for ( int i = 1; i < getSubclassTableSpan(); i++ ) { - final String subclassTableName = getSubclassTableName( i ); - if ( subclassTableName.equals( joinTableExpression ) ) { + if ( getSubclassTableName( i ).equals( joinTableExpression ) ) { return generateTableReferenceJoin( lhs, joinTableExpression, @@ -1368,12 +1360,11 @@ protected TableReferenceJoin generateTableReferenceJoin( boolean innerJoin, String[] targetColumns, SqlAstCreationState creationState) { - final NamedTableReference joinedTableReference = new NamedTableReference( + final var joinedTableReference = new NamedTableReference( joinTableExpression, sqlAliasBase.generateNewAlias(), !innerJoin ); - return new TableReferenceJoin( innerJoin, joinedTableReference, @@ -1393,16 +1384,16 @@ protected Predicate generateJoinPredicate( String[] pkColumnNames, String[] fkColumnNames, SqlAstCreationState creationState) { - final EntityIdentifierMapping identifierMapping = getIdentifierMapping(); + final var identifierMapping = getIdentifierMapping(); - final Junction conjunction = new Junction( Junction.Nature.CONJUNCTION ); + final var conjunction = new Junction( Junction.Nature.CONJUNCTION ); assert pkColumnNames.length == fkColumnNames.length; assert pkColumnNames.length == identifierMapping.getJdbcTypeCount(); identifierMapping.forEachSelectable( (columnIndex, selection) -> { - final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver(); + final var sqlExpressionResolver = creationState.getSqlExpressionResolver(); final String rootPkColumnName = pkColumnNames[ columnIndex ]; final Expression pkColumnExpression = sqlExpressionResolver.resolveSqlExpression( @@ -1455,7 +1446,7 @@ private Object initializedLazyField( Object entity, SharedSessionContractImplementor session) { final Object id = session.getContextEntityIdentifier( entity ); - final EntityEntry entry = session.getPersistenceContext().getEntry( entity ); + final var entry = session.getPersistenceContext().getEntry( entity ); if ( entry == null ) { throw new HibernateException( "entity is not associated with the session: " + id ); } @@ -1470,9 +1461,9 @@ private Object initializedLazyField( // attempt to read it from second-level cache if ( session.getCacheMode().isGetEnabled() - && canReadFromCache() - && isLazyPropertiesCacheable() ) { - final EntityDataAccess cacheAccess = getCacheAccessStrategy(); + && canReadFromCache() + && isLazyPropertiesCacheable() ) { + final var cacheAccess = getCacheAccessStrategy(); final Object cacheKey = cacheAccess.generateCacheKey( id, @@ -1480,9 +1471,9 @@ && isLazyPropertiesCacheable() ) { session.getFactory(), session.getTenantIdentifier() ); - final Object ce = CacheHelper.fromSharedCache( session, cacheKey, this, cacheAccess ); - if ( ce != null ) { - final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure( ce, factory ); + final Object structuredEntry = fromSharedCache( session, cacheKey, this, cacheAccess ); + if ( structuredEntry != null ) { + final var cacheEntry = (CacheEntry) getCacheEntryStructure().destructure( structuredEntry, factory ); final Object initializedValue = initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); if ( initializedValue != LazyPropertyInitializer.UNFETCHED_PROPERTY ) { // The following should be redundant, since the setter should have set this already. @@ -1504,41 +1495,31 @@ private PersistentCollection initializedLazyCollection( SharedSessionContractImplementor session) { // a collection attribute is being accessed via enhancement: // we can circumvent all the rest and just return the PersistentCollection - final CollectionPersister persister = + final var persister = factory.getMappingMetamodel() .getCollectionDescriptor( collectionType.getRole() ); - // Get/create the collection, and make sure it is initialized! This initialized part is + // Get/create the collection, and make sure it is initialized! This initialized part is // different from proxy-based scenarios where we have to create the PersistentCollection - // reference "ahead of time" to add as a reference to the proxy. For bytecode solutions + // reference "ahead of time" to add as a reference to the proxy. For bytecode solutions // we are not creating the PersistentCollection ahead of time, but instead we are creating // it on first request through the enhanced entity. // see if there is already a collection instance associated with the session - // NOTE : can this ever happen? - final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); - final EntityEntry entry = persistenceContext.getEntry( entity ); - final Object key = getCollectionKey( persister, entity, entry, session ); - assert key != null; - PersistentCollection collection = - persistenceContext.getCollection( new CollectionKey( persister, key ) ); - if ( collection == null ) { - collection = collectionType.instantiate( session, persister, key ); - collection.setOwner( entity ); - persistenceContext.addUninitializedCollection( persister, collection, key ); - } + // NOTE: can this ever happen? + var collection = getCollection( entity, collectionType, session, persister ); final var interceptor = asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor(); assert interceptor != null : "Expecting bytecode interceptor to be non-null"; interceptor.attributeInitialized( fieldName ); + final var persistenceContext = session.getPersistenceContextInternal(); if ( collectionType.isArrayType() ) { persistenceContext.addCollectionHolder( collection ); } - - // update the "state" of the entity's EntityEntry to over-write UNFETCHED_PROPERTY reference - // for the collection to the just loaded collection - final EntityEntry ownerEntry = persistenceContext.getEntry( entity ); + // update the "state" of the owning entity's EntityEntry to overwrite the + // UNFETCHED_PROPERTY for the collection to the just-loaded collection + final var ownerEntry = persistenceContext.getEntry( entity ); if ( ownerEntry == null ) { // the entity is not in the session; it was probably deleted, // so we cannot load the collection anymore. @@ -1551,18 +1532,39 @@ private PersistentCollection initializedLazyCollection( return collection; } + private static PersistentCollection getCollection( + Object entity, + CollectionType collectionType, + SharedSessionContractImplementor session, + CollectionPersister persister) { + final var persistenceContext = session.getPersistenceContextInternal(); + final var entry = persistenceContext.getEntry( entity ); + final Object key = getCollectionKey( persister, entity, entry, session ); + assert key != null; + final var collection = persistenceContext.getCollection( new CollectionKey( persister, key ) ); + if ( collection == null ) { + final var newCollection = collectionType.instantiate( session, persister, key ); + newCollection.setOwner( entity ); + persistenceContext.addUninitializedCollection( persister, newCollection, key ); + return newCollection; + } + else { + return collection; + } + } + public @Nullable static Object getCollectionKey( CollectionPersister persister, Object owner, EntityEntry ownerEntry, SharedSessionContractImplementor session) { - final CollectionType collectionType = persister.getCollectionType(); + final var collectionType = persister.getCollectionType(); if ( ownerEntry != null ) { // this call only works when the owner is associated with the Session, which is not always the case return collectionType.getKeyOfOwner( owner, session ); } else { - final EntityPersister ownerPersister = persister.getOwnerEntityPersister(); + final var ownerPersister = persister.getOwnerEntityPersister(); return collectionType.getLHSPropertyName() == null // collection key is defined by the owning entity identifier ? ownerPersister.getIdentifier( owner, session ) @@ -1604,11 +1606,10 @@ private Object initLazyProperties( final String fetchGroup = lazyAttributesMetadata.getFetchGroupName( fieldName ); final var fetchGroupAttributeDescriptors = lazyAttributesMetadata.getFetchGroupAttributeDescriptors( fetchGroup ); - - final SingleIdArrayLoadPlan lazySelect = getSQLLazySelectLoadPlan( fetchGroup ); + final var lazySelectLoadPlan = getSQLLazySelectLoadPlan( fetchGroup ); try { Object finalResult = null; - final Object[] results = lazySelect.load( id, session ); + final Object[] results = lazySelectLoadPlan.load( id, session ); int i = 0; for ( var fetchGroupAttributeDescriptor : fetchGroupAttributeDescriptors ) { final String attributeName = fetchGroupAttributeDescriptor.getName(); @@ -1655,12 +1656,11 @@ private Object initLazyProperty( // An eager property can be lazy because of an applied EntityGraph final int propertyIndex = getPropertyIndex( fieldName ); final List partsToSelect = List.of( getAttributeMapping( propertyIndex ) ); - final SingleIdArrayLoadPlan lazyLoanPlan = getOrCreateLazyLoadPlan( fieldName, partsToSelect ); + final var lazyLoanPlan = getOrCreateLazyLoadPlan( fieldName, partsToSelect ); try { final Object[] results = lazyLoanPlan.load( id, session ); final Object result = results[0]; - initializeLazyProperty( entity, entry, result, propertyIndex, - getPropertyTypes()[propertyIndex] ); + initializeLazyProperty( entity, entry, result, propertyIndex, getPropertyTypes()[propertyIndex] ); return result; } catch (JDBCException ex) { @@ -1674,25 +1674,19 @@ private Object initLazyProperty( } private SingleIdArrayLoadPlan getOrCreateLazyLoadPlan(String fieldName, List partsToSelect) { - var propertyLoadPlansByName = nonLazyPropertyLoadPlansByName; - if ( propertyLoadPlansByName == null ) { - propertyLoadPlansByName = new ConcurrentHashMap<>(); - final SingleIdArrayLoadPlan newLazyLoanPlan = createLazyLoanPlan( partsToSelect ); - propertyLoadPlansByName.put( fieldName, newLazyLoanPlan ); - nonLazyPropertyLoadPlansByName = propertyLoadPlansByName; - return newLazyLoanPlan; + final var plans = nonLazyPropertyLoadPlansByName; + if ( plans == null ) { + nonLazyPropertyLoadPlansByName = new ConcurrentHashMap<>(); } else { - final SingleIdArrayLoadPlan lazyLoanPlan = nonLazyPropertyLoadPlansByName.get( fieldName ); - if ( lazyLoanPlan == null ) { - final SingleIdArrayLoadPlan newLazyLoanPlan = createLazyLoanPlan( partsToSelect ); - nonLazyPropertyLoadPlansByName.put( fieldName, newLazyLoanPlan ); - return newLazyLoanPlan; - } - else { + final var lazyLoanPlan = plans.get( fieldName ); + if ( lazyLoanPlan != null ) { return lazyLoanPlan; } } + final var newLazyLoanPlan = createLazyLoanPlan( partsToSelect ); + nonLazyPropertyLoadPlansByName.put( fieldName, newLazyLoanPlan ); + return newLazyLoanPlan; } protected Object initializeLazyPropertiesFromCache( @@ -1703,19 +1697,17 @@ protected Object initializeLazyPropertiesFromCache( final CacheEntry cacheEntry) { LOG.trace( "Initializing lazy properties from second-level cache" ); Object result = null; - final Serializable[] disassembledValues = cacheEntry.getDisassembledState(); + final var disassembledValues = cacheEntry.getDisassembledState(); for ( int j = 0; j < lazyPropertyNames.length; j++ ) { - final Serializable cachedValue = disassembledValues[lazyPropertyNumbers[j]]; - final Type lazyPropertyType = lazyPropertyTypes[j]; - final String propertyName = lazyPropertyNames[j]; + final var cachedValue = disassembledValues[lazyPropertyNumbers[j]]; if ( cachedValue == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { - if ( fieldName.equals(propertyName) ) { + if ( fieldName.equals( lazyPropertyNames[j] ) ) { result = LazyPropertyInitializer.UNFETCHED_PROPERTY; } // don't try to initialize the unfetched property } else { - final Object propValue = lazyPropertyType.assemble( cachedValue, session, entity ); + final Object propValue = lazyPropertyTypes[j].assemble( cachedValue, session, entity ); if ( initializeLazyProperty( fieldName, entity, entry, j, propValue ) ) { result = propValue; } @@ -1734,18 +1726,25 @@ protected boolean initializeLazyProperty( final EntityEntry entry, final int index, final Object propValue) { - setPropertyValue( entity, lazyPropertyNumbers[index], propValue ); - if ( entry.getLoadedState() != null ) { + final int propertyNumber = lazyPropertyNumbers[index]; + setPropertyValue( entity, propertyNumber, propValue ); + final var loadedState = entry.getLoadedState(); + if ( loadedState != null ) { // object have been loaded with setReadOnly(true); HHH-2236 - entry.getLoadedState()[lazyPropertyNumbers[index]] = lazyPropertyTypes[index].deepCopy( propValue, factory ); + loadedState[propertyNumber] = copiedLazyPropertyValue( index, propValue ); } // If the entity has deleted state, then update that as well - if ( entry.getDeletedState() != null ) { - entry.getDeletedState()[lazyPropertyNumbers[index]] = lazyPropertyTypes[index].deepCopy( propValue, factory ); + final var deletedState = entry.getDeletedState(); + if ( deletedState != null ) { + deletedState[propertyNumber] = copiedLazyPropertyValue( index, propValue ); } return fieldName.equals( lazyPropertyNames[index] ); } + private Object copiedLazyPropertyValue(int index, Object propValue) { + return lazyPropertyTypes[index].deepCopy( propValue, factory ); + } + // Used by Hibernate Reactive protected boolean initializeLazyProperty( final String fieldName, @@ -1763,13 +1762,13 @@ protected boolean initializeLazyProperty( // Used by Hibernate Reactive protected void initializeLazyProperty(Object entity, EntityEntry entry, Object propValue, int index, Type type) { setPropertyValue( entity, index, propValue ); - final Object[] loadedState = entry.getLoadedState(); + final var loadedState = entry.getLoadedState(); if ( loadedState != null ) { // object have been loaded with setReadOnly(true); HHH-2236 loadedState[index] = type.deepCopy( propValue, factory ); } // If the entity has deleted state, then update that as well - final Object[] deletedState = entry.getDeletedState(); + final var deletedState = entry.getDeletedState(); if ( deletedState != null ) { deletedState[index] = type.deepCopy( propValue, factory ); } @@ -1846,8 +1845,8 @@ public boolean isLazyPropertiesCacheable() { @Override public String selectFragment(String alias, String suffix) { - final QuerySpec rootQuerySpec = new QuerySpec( true ); - final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState( + final var rootQuerySpec = new QuerySpec( true ); + final var sqlAstCreationState = new LoaderSqlAstCreationState( rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), @@ -1858,8 +1857,8 @@ public String selectFragment(String alias, String suffix) { factory.getSqlTranslationEngine() ); - final NavigablePath entityPath = new NavigablePath( getRootPathName() ); - final TableGroup rootTableGroup = createRootTableGroup( + final var entityPath = new NavigablePath( getRootPathName() ); + final var rootTableGroup = createRootTableGroup( true, entityPath, null, @@ -1874,13 +1873,12 @@ public String selectFragment(String alias, String suffix) { createDomainResult( entityPath, rootTableGroup, null, sqlAstCreationState ); // Wrap expressions with aliases - final SelectClause selectClause = rootQuerySpec.getSelectClause(); - final List sqlSelections = selectClause.getSqlSelections(); + final var sqlSelections = rootQuerySpec.getSelectClause().getSqlSelections(); final Set processedExpressions = new HashSet<>( sqlSelections.size() ); int i = 0; final int identifierSelectionSize = identifierMapping.getJdbcTypeCount(); for ( int j = 0; j < identifierSelectionSize; j++ ) { - final SelectableMapping selectableMapping = identifierMapping.getSelectable( j ); + final var selectableMapping = identifierMapping.getSelectable( j ); if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) { aliasSelection( sqlSelections, i, identifierAliases[j] + suffix ); i++; @@ -1889,7 +1887,7 @@ public String selectFragment(String alias, String suffix) { if ( hasSubclasses() ) { assert discriminatorMapping.getJdbcTypeCount() == 1; - final SelectableMapping selectableMapping = discriminatorMapping.getSelectable( 0 ); + final var selectableMapping = discriminatorMapping.getSelectable( 0 ); if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) { aliasSelection( sqlSelections, i, getDiscriminatorAlias() + suffix ); i++; @@ -1897,8 +1895,7 @@ public String selectFragment(String alias, String suffix) { } if ( hasRowId() ) { - final SelectableMapping selectableMapping = rowIdMapping; - if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) { + if ( processedExpressions.add( rowIdMapping.getSelectionExpression() ) ) { aliasSelection( sqlSelections, i, ROWID_ALIAS + suffix ); i++; } @@ -1912,17 +1909,17 @@ public String selectFragment(String alias, String suffix) { // getSubclassColumnAliasClosure contains the _identifierMapper columns when it has an id class, // which need to be skipped if ( identifierMapping instanceof NonAggregatedIdentifierMapping nonAggregatedIdentifierMapping - && nonAggregatedIdentifierMapping.getIdClassEmbeddable() != null ) { + && nonAggregatedIdentifierMapping.getIdClassEmbeddable() != null ) { columnIndex = identifierSelectionSize; } for ( int j = 0; j < size; j++ ) { - final AttributeMapping fetchable = getFetchable( j ); + final var fetchable = getFetchable( j ); if ( !(fetchable instanceof PluralAttributeMapping) - && !skipFetchable( fetchable, fetchable.getMappedFetchOptions().getTiming() ) - && fetchable.isSelectable() ) { + && !skipFetchable( fetchable, fetchable.getMappedFetchOptions().getTiming() ) + && fetchable.isSelectable() ) { final int jdbcTypeCount = fetchable.getJdbcTypeCount(); for ( int k = 0; k < jdbcTypeCount; k++ ) { - final SelectableMapping selectableMapping = fetchable.getSelectable( k ); + final var selectableMapping = fetchable.getSelectable( k ); if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) { final String baseAlias = selectableMapping.isFormula() ? formulaAliases[formulaIndex++] @@ -1949,28 +1946,26 @@ private static void aliasSelection( List sqlSelections, int selectionIndex, String alias) { - final Expression expression = sqlSelections.get( selectionIndex ).getExpression(); - sqlSelections.set( - selectionIndex, - new SqlSelectionImpl( selectionIndex, new AliasedExpression( expression, alias ) ) - ); + final var expression = sqlSelections.get( selectionIndex ).getExpression(); + sqlSelections.set( selectionIndex, + new SqlSelectionImpl( selectionIndex, new AliasedExpression( expression, alias ) ) ); } private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstCreationState creationState) { - final FetchableContainer fetchableContainer = fetchParent.getReferencedMappingContainer(); + final var fetchableContainer = fetchParent.getReferencedMappingContainer(); final int size = fetchableContainer.getNumberOfFetchables(); - final ImmutableFetchList.Builder fetches = new ImmutableFetchList.Builder( fetchableContainer ); + final var fetches = new ImmutableFetchList.Builder( fetchableContainer ); for ( int i = 0; i < size; i++ ) { - final Fetchable fetchable = fetchableContainer.getFetchable( i ); + final var fetchable = fetchableContainer.getFetchable( i ); // Ignore plural attributes if ( !( fetchable instanceof PluralAttributeMapping ) ) { - final FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming(); + final var fetchTiming = fetchable.getMappedFetchOptions().getTiming(); if ( !skipFetchable( fetchable, fetchTiming ) ) { if ( fetchTiming == null ) { throw new AssertionFailure( "fetchTiming was null" ); } if ( fetchable.isSelectable() ) { - final Fetch fetch = fetchParent.generateFetchableFetch( + final var fetch = fetchParent.generateFetchableFetch( fetchable, fetchParent.resolveNavigablePath( fetchable ), fetchTiming, @@ -2021,7 +2016,7 @@ public String getDiscriminatorAlias(String suffix) { // NOTE: this assumes something about how propertySelectFragment is implemented by the subclass! // toUnquotedAliasStrings( getDiscriminatorColumnName() ) before - now tried // to remove that unquoting and missing aliases - return entityMetamodel.hasSubclasses() + return hasSubclasses() ? new Alias( suffix ).toAliasString( getDiscriminatorAlias() ) : null; } @@ -2034,11 +2029,8 @@ public Object[] getDatabaseSnapshot(Object id, SharedSessionContractImplementor @Override public Object getIdByUniqueKey(Object key, String uniquePropertyName, SharedSessionContractImplementor session) { if ( LOG.isTraceEnabled() ) { - LOG.tracef( - "resolving unique key [%s] to identifier for entity [%s]", - key, - getEntityName() - ); + LOG.tracef( "resolving unique key [%s] to identifier for entity [%s]", + key, getEntityName() ); } return getUniqueKeyLoader( uniquePropertyName, session ).resolveId( key, session ); @@ -2049,7 +2041,7 @@ public Object getIdByUniqueKey(Object key, String uniquePropertyName, SharedSess * Generate the SQL that selects the version number by id */ public String generateSelectVersionString() { - final SimpleSelect select = new SimpleSelect( getFactory() ).setTableName( getVersionedTableName() ); + final var select = new SimpleSelect( getFactory() ).setTableName( getVersionedTableName() ); if ( isVersioned() ) { select.addColumn( getVersionColumnName(), VERSION_COLUMN_ALIAS ); } @@ -2144,26 +2136,30 @@ public Object getCurrentVersion(Object id, SharedSessionContractImplementor sess } final String versionSelectString = getVersionSelectString(); try { - final JdbcCoordinator jdbcCoordinator = session.getJdbcCoordinator(); - final PreparedStatement st = jdbcCoordinator.getStatementPreparer().prepareStatement( versionSelectString ); + final var jdbcCoordinator = session.getJdbcCoordinator(); + final var statement = jdbcCoordinator.getStatementPreparer().prepareStatement( versionSelectString ); + final var resourceRegistry = jdbcCoordinator.getLogicalConnection().getResourceRegistry(); try { - getIdentifierType().nullSafeSet( st, id, 1, session ); - final ResultSet rs = jdbcCoordinator.getResultSetReturn().extract( st, versionSelectString ); + getIdentifierType().nullSafeSet( statement, id, 1, session ); + final var resultSet = jdbcCoordinator.getResultSetReturn().extract( statement, versionSelectString ); try { - if ( !rs.next() ) { + if ( !resultSet.next() ) { return null; } - if ( !isVersioned() ) { + else if ( !isVersioned() ) { return this; } - return getVersionMapping().getJdbcMapping().getJdbcValueExtractor().extract( rs, 1, session ); + else { + return getVersionMapping().getJdbcMapping().getJdbcValueExtractor() + .extract( resultSet, 1, session ); + } } finally { - jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( rs, st ); + resourceRegistry.release( resultSet, statement ); } } finally { - jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( st ); + resourceRegistry.release( statement ); jdbcCoordinator.afterStatementExecution(); } } @@ -2277,17 +2273,17 @@ public DiscriminatorType getDiscriminatorDomainType() { } private DiscriminatorType buildDiscriminatorType() { - final BasicType underlyingJdbcMapping = getDiscriminatorType(); - return underlyingJdbcMapping == null + final var discriminatorBasicType = getDiscriminatorType(); + return discriminatorBasicType == null ? null : new DiscriminatorTypeImpl<>( - underlyingJdbcMapping, + discriminatorBasicType, new UnifiedAnyDiscriminatorConverter<>( getNavigableRole() .append( EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME ), factory.getTypeConfiguration().getJavaTypeRegistry() .resolveDescriptor( discriminatedType() ), - underlyingJdbcMapping.getRelationalJavaType(), + discriminatorBasicType.getRelationalJavaType(), getSubclassByDiscriminatorValue(), null, factory.getMappingMetamodel() @@ -2316,7 +2312,7 @@ public static String generateTableAlias(String rootAlias, int tableNumber) { } private int getSubclassPropertyIndex(String propertyName) { - return ArrayHelper.indexOf( subclassPropertyNameClosure, propertyName ); + return indexOf( subclassPropertyNameClosure, propertyName ); } public String[] getPropertyColumnNames(int i) { @@ -2379,7 +2375,7 @@ private static boolean isPrefix(final AttributeMapping attributeMapping, final S @Override public int[] resolveAttributeIndexes(String[] attributeNames) { if ( attributeNames == null || attributeNames.length == 0 ) { - return ArrayHelper.EMPTY_INT_ARRAY; + return EMPTY_INT_ARRAY; } final List fields = new ArrayList<>( attributeNames.length ); @@ -2388,7 +2384,7 @@ public int[] resolveAttributeIndexes(String[] attributeNames) { int index = 0; for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); + final var attributeMapping = attributeMappings.get( i ); if ( isPrefix( attributeMapping, attributeNames[index] ) ) { fields.add( attributeMapping.getStateArrayPosition() ); index++; @@ -2418,16 +2414,19 @@ public int[] resolveDirtyAttributeIndexes( final Object[] previousState, final String[] attributeNames, final SessionImplementor session) { - final BitSet mutablePropertiesIndexes = entityMetamodel.getMutablePropertiesIndexes(); - final int estimatedSize = attributeNames == null ? 0 : attributeNames.length + mutablePropertiesIndexes.cardinality(); + final BitSet mutablePropertiesIndexes = getMutablePropertiesIndexes(); + final int estimatedSize = + attributeNames == null + ? 0 + : attributeNames.length + mutablePropertiesIndexes.cardinality(); final List fields = new ArrayList<>( estimatedSize ); if ( estimatedSize == 0 ) { - return ArrayHelper.EMPTY_INT_ARRAY; + return EMPTY_INT_ARRAY; } if ( !mutablePropertiesIndexes.isEmpty() ) { // We have to check the state for "mutable" properties as dirty tracking isn't aware of mutable types - final Type[] propertyTypes = entityMetamodel.getPropertyTypes(); - final boolean[] propertyCheckability = entityMetamodel.getPropertyCheckability(); + final Type[] propertyTypes = getPropertyTypes(); + final boolean[] propertyCheckability = getPropertyCheckability(); for ( int i = mutablePropertiesIndexes.nextSetBit(0); i >= 0; i = mutablePropertiesIndexes.nextSetBit(i + 1) ) { // This is kindly borrowed from org.hibernate.type.TypeHelper.findDirty @@ -2438,7 +2437,7 @@ public int[] resolveDirtyAttributeIndexes( } if ( attributeNames.length != 0 ) { - final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability(); + final boolean[] propertyUpdateability = getPropertyUpdateability(); if ( superMappingType == null ) { /* Sort attribute names so that we can traverse mappings efficiently @@ -2461,7 +2460,7 @@ class ChildEntity extends SuperEntity { Arrays.sort( attributeNames ); int index = 0; for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); + final var attributeMapping = attributeMappings.get( i ); final String attributeName = attributeMapping.getAttributeName(); if ( isPrefix( attributeMapping, attributeNames[index] ) ) { final int position = attributeMapping.getStateArrayPosition(); @@ -2488,7 +2487,7 @@ class ChildEntity extends SuperEntity { } else { for ( String attributeName : attributeNames ) { - final Integer index = entityMetamodel.getPropertyIndexOrNull( attributeName ); + final Integer index = getPropertyIndexOrNull( attributeName ); if ( index != null && propertyUpdateability[index] && !fields.contains( index ) ) { fields.add( index ); } @@ -2539,15 +2538,11 @@ public Object loadByUniqueKey( private Map> uniqueKeyLoadersNew; protected SingleUniqueKeyEntityLoader getUniqueKeyLoader(String attributeName, SharedSessionContractImplementor session) { - final SingularAttributeMapping attribute = (SingularAttributeMapping) findByPath( attributeName ); - final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers(); + final var attribute = (SingularAttributeMapping) findByPath( attributeName ); + final var influencers = session.getLoadQueryInfluencers(); // no subselect fetching for entities for now if ( isAffectedByInfluencers( influencers, true ) ) { - return new SingleUniqueKeyEntityLoaderStandard<>( - this, - attribute, - influencers - ); + return new SingleUniqueKeyEntityLoaderStandard<>( this, attribute, influencers ); } final SingleUniqueKeyEntityLoader existing; if ( uniqueKeyLoadersNew == null ) { @@ -2563,17 +2558,13 @@ protected SingleUniqueKeyEntityLoader getUniqueKeyLoader(String attributeName } else { final SingleUniqueKeyEntityLoader loader = - new SingleUniqueKeyEntityLoaderStandard<>( this, attribute, new LoadQueryInfluencers( factory ) ); + new SingleUniqueKeyEntityLoaderStandard<>( this, attribute, + new LoadQueryInfluencers( factory ) ); uniqueKeyLoadersNew.put( attribute, loader ); return loader; } } - @Override - public int getPropertyIndex(String propertyName) { - return entityMetamodel.getPropertyIndex( propertyName ); - } - private void initOrdinaryPropertyPaths(Metadata mapping) throws MappingException { for ( int i = 0; i < getSubclassPropertyNameClosure().length; i++ ) { propertyMapping.initPropertyPaths( @@ -2589,20 +2580,20 @@ private void initOrdinaryPropertyPaths(Metadata mapping) throws MappingException } private void initIdentifierPropertyPaths(Metadata mapping) throws MappingException { - String idProp = getIdentifierPropertyName(); + final String idProp = getIdentifierPropertyName(); if ( idProp != null ) { propertyMapping.initPropertyPaths( idProp, getIdentifierType(), getIdentifierColumnNames(), getIdentifierColumnReaders(), getIdentifierColumnReaderTemplates(), null, mapping ); } - if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) { + if ( getIdentifierProperty().isEmbedded() ) { propertyMapping.initPropertyPaths( null, getIdentifierType(), getIdentifierColumnNames(), getIdentifierColumnReaders(), getIdentifierColumnReaderTemplates(), null, mapping ); } - if ( !entityMetamodel.hasNonIdentifierPropertyNamedId() ) { + if ( !hasNonIdentifierPropertyNamedId() ) { propertyMapping.initPropertyPaths( ENTITY_ID, getIdentifierType(), getIdentifierColumnNames(), getIdentifierColumnReaders(), getIdentifierColumnReaderTemplates(), null, mapping @@ -2626,7 +2617,7 @@ protected void initPropertyPaths(Metadata mapping) throws MappingException { initOrdinaryPropertyPaths( mapping ); initOrdinaryPropertyPaths( mapping ); //do two passes, for collection property-ref! initIdentifierPropertyPaths( mapping ); - if ( entityMetamodel.isPolymorphic() ) { + if ( isPolymorphic() ) { initDiscriminatorPropertyPath( mapping ); } } @@ -2643,9 +2634,10 @@ public String getSelectByUniqueKeyString(String propertyName) { @Override public String getSelectByUniqueKeyString(String[] propertyNames) { - final SimpleSelect select = new SimpleSelect( getFactory() ) - .setTableName( getTableName(0) ) - .addColumns( getKeyColumns(0) ); + final var select = + new SimpleSelect( getFactory() ) + .setTableName( getTableName(0) ) + .addColumns( getKeyColumns(0) ); for ( String propertyName : propertyNames ) { select.addRestriction( getPropertyColumnNames( propertyName ) ); } @@ -2654,9 +2646,10 @@ public String getSelectByUniqueKeyString(String[] propertyNames) { @Override public String getSelectByUniqueKeyString(String[] propertyNames, String[] columnNames) { - final SimpleSelect select = new SimpleSelect( getFactory() ) - .setTableName( getTableName( 0 ) ) - .addColumns( columnNames ); + final var select = + new SimpleSelect( getFactory() ) + .setTableName( getTableName( 0 ) ) + .addColumns( columnNames ); for ( final String propertyName : propertyNames ) { select.addRestriction( getPropertyColumnNames( propertyName ) ); } @@ -2736,18 +2729,18 @@ protected void logStaticSQL() { if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) { MODEL_MUTATION_LOGGER.tracef( "Static SQL for entity: %s", getEntityName() ); for ( var entry : lazyLoadPlanByFetchGroup.entrySet() ) { - MODEL_MUTATION_LOGGER.tracef( " Lazy select (%s) : %s", entry.getKey(), entry.getValue().getJdbcSelect().getSqlString() ); + MODEL_MUTATION_LOGGER.tracef( " Lazy select (%s) : %s", + entry.getKey(), entry.getValue().getJdbcSelect().getSqlString() ); } if ( sqlVersionSelectString != null ) { MODEL_MUTATION_LOGGER.tracef( " Version select: %s", sqlVersionSelectString ); } { - final MutationOperationGroup staticInsertGroup = insertCoordinator.getStaticMutationOperationGroup(); + final var staticInsertGroup = insertCoordinator.getStaticMutationOperationGroup(); if ( staticInsertGroup != null ) { for ( int i = 0; i < staticInsertGroup.getNumberOfOperations(); i++ ) { - final MutationOperation mutation = staticInsertGroup.getOperation( i ); - if ( mutation instanceof JdbcOperation jdbcOperation ) { + if ( staticInsertGroup.getOperation( i ) instanceof JdbcOperation jdbcOperation ) { MODEL_MUTATION_LOGGER.tracef( " Insert (%s): %s", i, jdbcOperation.getSqlString() ); } } @@ -2755,11 +2748,10 @@ protected void logStaticSQL() { } { - final MutationOperationGroup staticUpdateGroup = updateCoordinator.getStaticMutationOperationGroup(); + final var staticUpdateGroup = updateCoordinator.getStaticMutationOperationGroup(); if ( staticUpdateGroup != null ) { for ( int i = 0; i < staticUpdateGroup.getNumberOfOperations(); i++ ) { - final MutationOperation mutation = staticUpdateGroup.getOperation( i ); - if ( mutation instanceof JdbcOperation jdbcOperation ) { + if ( staticUpdateGroup.getOperation( i ) instanceof JdbcOperation jdbcOperation ) { MODEL_MUTATION_LOGGER.tracef( " Update (%s): %s", i, jdbcOperation.getSqlString() ); } } @@ -2767,11 +2759,10 @@ protected void logStaticSQL() { } { - final MutationOperationGroup staticDeleteGroup = deleteCoordinator.getStaticMutationOperationGroup(); + final var staticDeleteGroup = deleteCoordinator.getStaticMutationOperationGroup(); if ( staticDeleteGroup != null ) { for ( int i = 0; i < staticDeleteGroup.getNumberOfOperations(); i++ ) { - final MutationOperation mutation = staticDeleteGroup.getOperation( i ); - if ( mutation instanceof JdbcOperation jdbcOperation ) { + if ( staticDeleteGroup.getOperation( i ) instanceof JdbcOperation jdbcOperation ) { MODEL_MUTATION_LOGGER.tracef( " Delete (%s): %s", i, jdbcOperation.getSqlString() ); } } @@ -2881,7 +2872,7 @@ public void applyDiscriminator( SqlAstCreationState creationState) { if ( needsDiscriminator() ) { assert !creationState.supportsEntityNameUsage() : "Entity name usage should have been used instead"; - final Collection subMappingTypes = getSubMappingTypes(); + final var subMappingTypes = getSubMappingTypes(); final Map entityNameUseMap = new HashMap<>( 1 + subMappingTypes.size() + ( isInherited() ? 1 : 0 ) ); if ( subMappingTypes.isEmpty() ) { @@ -2981,7 +2972,7 @@ else if ( hasNonNull ) { return new NullnessPredicate( sqlExpression, true ); } else if ( hasNull ) { - final Junction junction = new Junction( Junction.Nature.DISJUNCTION ); + final var junction = new Junction( Junction.Nature.DISJUNCTION ); junction.add( new NullnessPredicate( sqlExpression ) ); junction.add( discriminatorValuesPredicate( discriminatorType, sqlExpression ) ); return junction; @@ -3005,7 +2996,7 @@ protected String getPrunedDiscriminatorPredicate( Map entityNameUses, MappingMetamodelImplementor mappingMetamodel, String alias) { - final InFragment fragment = new InFragment(); + final var fragment = new InFragment(); if ( isDiscriminatorFormula() ) { fragment.setFormula( alias, getDiscriminatorFormulaTemplate() ); } @@ -3013,13 +3004,13 @@ protected String getPrunedDiscriminatorPredicate( fragment.setColumn( alias, getDiscriminatorColumnName() ); } boolean containsNotNull = false; - for ( Map.Entry entry : entityNameUses.entrySet() ) { - final EntityNameUse.UseKind useKind = entry.getValue().getKind(); + for ( var entry : entityNameUses.entrySet() ) { + final var useKind = entry.getValue().getKind(); if ( useKind == EntityNameUse.UseKind.PROJECTION || useKind == EntityNameUse.UseKind.EXPRESSION ) { // We only care about treat and filter uses which allow to reduce the amount of rows to select continue; } - final EntityPersister persister = mappingMetamodel.getEntityDescriptor( entry.getKey() ); + final var persister = mappingMetamodel.getEntityDescriptor( entry.getKey() ); // Filtering for abstract entities makes no sense, so ignore that // Also, it makes no sense to filter for any of the super types, // as the query will contain a filter for that already anyway @@ -3028,7 +3019,7 @@ protected String getPrunedDiscriminatorPredicate( fragment.addValue( persister.getDiscriminatorSQLValue() ); } } - final AbstractEntityPersister rootEntityDescriptor = (AbstractEntityPersister) getRootEntityDescriptor(); + final var rootEntityDescriptor = (AbstractEntityPersister) getRootEntityDescriptor(); final List discriminatorSQLValues = Arrays.asList( rootEntityDescriptor.fullDiscriminatorSQLValues ); if ( fragment.getValues().size() == discriminatorSQLValues.size() ) { // Nothing to prune if we filter for all subtypes @@ -3036,28 +3027,26 @@ protected String getPrunedDiscriminatorPredicate( } if ( containsNotNull ) { - final String lhs; - if ( isDiscriminatorFormula() ) { - lhs = StringHelper.replace( getDiscriminatorFormulaTemplate(), Template.TEMPLATE, alias ); - } - else { - lhs = qualifyConditionally( alias, getDiscriminatorColumnName() ); - } + final String lhs = isDiscriminatorFormula() + ? StringHelper.replace( getDiscriminatorFormulaTemplate(), Template.TEMPLATE, alias ) + : qualifyConditionally( alias, getDiscriminatorColumnName() ); final List actualDiscriminatorSQLValues = new ArrayList<>( discriminatorSQLValues.size() ); for ( String value : discriminatorSQLValues ) { if ( !fragment.getValues().contains( value ) && !InFragment.NULL.equals( value ) ) { actualDiscriminatorSQLValues.add( value ); } } - final StringBuilder sb = new StringBuilder( 70 + actualDiscriminatorSQLValues.size() * 10 ).append( " or " ); + final var sql = + new StringBuilder( 70 + actualDiscriminatorSQLValues.size() * 10 ) + .append( " or " ); if ( !actualDiscriminatorSQLValues.isEmpty() ) { - sb.append( lhs ).append( " is not in (" ); - sb.append( String.join( ",", actualDiscriminatorSQLValues ) ); - sb.append( ") and " ); + sql.append( lhs ).append( " is not in (" ); + sql.append( String.join( ",", actualDiscriminatorSQLValues ) ); + sql.append( ") and " ); } - sb.append( lhs ).append( " is not null" ); + sql.append( lhs ).append( " is not null" ); fragment.getValues().remove( InFragment.NOT_NULL ); - return fragment.toFragmentString() + sb; + return fragment.toFragmentString() + sql; } else { return fragment.toFragmentString(); @@ -3073,12 +3062,11 @@ public void applyFilterRestrictions( boolean onlyApplyLoadByKeyFilters, SqlAstCreationState creationState) { if ( filterHelper != null ) { - final FilterAliasGenerator filterAliasGenerator = useQualifier && tableGroup != null - ? getFilterAliasGenerator( tableGroup ) - : null; filterHelper.applyEnabledFilters( predicateConsumer, - filterAliasGenerator, + useQualifier && tableGroup != null + ? getFilterAliasGenerator( tableGroup ) + : null, enabledFilters, onlyApplyLoadByKeyFilters, tableGroup, @@ -3129,15 +3117,11 @@ private String getAliasInWhere(TableGroup tableGroup, boolean useQualifier) { return null; } else { - final TableReference tableReference = tableGroup.resolveTableReference( sqlWhereStringTableExpression ); - if ( tableReference == null ) { - return null; - } - else { - return useQualifier && tableReference.getIdentificationVariable() != null - ? tableReference.getIdentificationVariable() - : tableReference.getTableId(); - } + final var tableReference = tableGroup.resolveTableReference( sqlWhereStringTableExpression ); + return tableReference == null ? null : + useQualifier && tableReference.getIdentificationVariable() != null + ? tableReference.getIdentificationVariable() + : tableReference.getTableId(); } } @@ -3148,14 +3132,13 @@ protected boolean shouldInnerJoinSubclassTable(int subclassTableNumber, Set treatAsDeclarations) { @@ -3163,9 +3146,11 @@ protected boolean isSubclassTableIndicatedByTreatAsDeclarations(int subclassTabl } /** - * Post-construct is a callback for AbstractEntityPersister subclasses to call after they are all done with their - * constructor processing. It allows AbstractEntityPersister to extend its construction after all subclass-specific - * details have been handled. + * Post-construct is a callback for {@code AbstractEntityPersister} + * subclasses to call after they are all done with their constructor + * processing. It allows {@code AbstractEntityPersister} to extend + * its construction after subclass-specific details have all been + * taken care of. * * @param mapping The mapping * @@ -3189,12 +3174,14 @@ public void prepareLoaders() { private void doLateInit() { tableMappings = buildTableMappings(); - final List insertGeneratedAttributes = hasInsertGeneratedProperties() ? - GeneratedValuesProcessor.getGeneratedAttributes( this, INSERT ) - : emptyList(); - final List updateGeneratedAttributes = hasUpdateGeneratedProperties() ? - GeneratedValuesProcessor.getGeneratedAttributes( this, UPDATE ) - : emptyList(); + final List insertGeneratedAttributes = + hasInsertGeneratedProperties() + ? getGeneratedAttributes( this, INSERT ) + : emptyList(); + final List updateGeneratedAttributes = + hasUpdateGeneratedProperties() + ? getGeneratedAttributes( this, UPDATE ) + : emptyList(); insertGeneratedProperties = initInsertGeneratedProperties( insertGeneratedAttributes ); updateGeneratedProperties = initUpdateGeneratedProperties( updateGeneratedAttributes ); @@ -3207,10 +3194,12 @@ private void doLateInit() { } if ( hasInsertGeneratedProperties() ) { - insertGeneratedValuesProcessor = createGeneratedValuesProcessor( INSERT, insertGeneratedAttributes ); + insertGeneratedValuesProcessor = + createGeneratedValuesProcessor( INSERT, insertGeneratedAttributes ); } if ( hasUpdateGeneratedProperties() ) { - updateGeneratedValuesProcessor = createGeneratedValuesProcessor( UPDATE, updateGeneratedAttributes ); + updateGeneratedValuesProcessor = + createGeneratedValuesProcessor( UPDATE, updateGeneratedAttributes ); } insertCoordinator = buildInsertCoordinator(); @@ -3224,14 +3213,14 @@ private void doLateInit() { protected GeneratedValuesMutationDelegate createInsertDelegate() { if ( isIdentifierAssignedByInsert() ) { - final OnExecutionGenerator generator = (OnExecutionGenerator) getGenerator(); + final var generator = (OnExecutionGenerator) getGenerator(); return generator.getGeneratedIdentifierDelegate( this ); } - return GeneratedValuesHelper.getGeneratedValuesDelegate( this, INSERT ); + return getGeneratedValuesDelegate( this, INSERT ); } protected GeneratedValuesMutationDelegate createUpdateDelegate() { - return GeneratedValuesHelper.getGeneratedValuesDelegate( this, UPDATE ); + return getGeneratedValuesDelegate( this, UPDATE ); } private static class TableMappingBuilder { @@ -3378,8 +3367,8 @@ protected EntityTableMapping[] buildTableMappings() { deleteExpectations[ relativePosition ], customDeleteSql, deleteCallable[ relativePosition ], - entityMetamodel.isDynamicUpdate(), - entityMetamodel.isDynamicInsert() + isDynamicUpdate(), + isDynamicInsert() ); tableBuilderMap.put( tableExpression, tableMappingBuilder ); @@ -3393,12 +3382,12 @@ protected EntityTableMapping[] buildTableMappings() { } } ); - final EntityTableMapping[] list = new EntityTableMapping[tableBuilderMap.size()]; + final var entityTableMappings = new EntityTableMapping[tableBuilderMap.size()]; int i = 0; - for ( Map.Entry entry : tableBuilderMap.entrySet() ) { - list[i++] = entry.getValue().build(); + for ( var entry : tableBuilderMap.entrySet() ) { + entityTableMappings[i++] = entry.getValue().build(); } - return list; + return entityTableMappings; } /** @@ -3442,8 +3431,7 @@ protected InsertCoordinator buildInsertCoordinator() { protected UpdateCoordinator buildUpdateCoordinator() { // we only have updates to issue for entities with one or more singular attributes for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); - if ( attributeMapping instanceof SingularAttributeMapping ) { + if ( attributeMappings.get( i ) instanceof SingularAttributeMapping ) { return new UpdateCoordinatorStandard( this, factory ); } } @@ -3454,8 +3442,7 @@ protected UpdateCoordinator buildUpdateCoordinator() { protected UpdateCoordinator buildMergeCoordinator() { // we only have updates to issue for entities with one or more singular attributes for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); - if ( attributeMapping instanceof SingularAttributeMapping ) { + if ( attributeMappings.get( i ) instanceof SingularAttributeMapping ) { return new MergeCoordinator( this, factory ); } } @@ -3464,12 +3451,9 @@ protected UpdateCoordinator buildMergeCoordinator() { } protected DeleteCoordinator buildDeleteCoordinator() { - if ( softDeleteMapping == null ) { - return new DeleteCoordinatorStandard( this, factory ); - } - else { - return new DeleteCoordinatorSoft( this, factory ); - } + return softDeleteMapping == null + ? new DeleteCoordinatorStandard( this, factory ) + : new DeleteCoordinatorSoft( this, factory ); } @Override @@ -3538,7 +3522,7 @@ protected SingleIdEntityLoader determineLoaderToUse(SharedSessionContractImpl return getSingleIdLoader(); } - final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers(); + final var influencers = session.getLoadQueryInfluencers(); if ( isAffectedByInfluencers( influencers, true ) ) { return buildSingleIdEntityLoader( influencers, lockOptions ); } @@ -3577,28 +3561,27 @@ public Object initializeEnhancedEntityUsedAsProxy( if ( enhancementMetadata.extractLazyInterceptor( entity ) instanceof EnhancementAsProxyLazinessInterceptor proxyInterceptor ) { - final EntityKey entityKey = proxyInterceptor.getEntityKey(); + final var entityKey = proxyInterceptor.getEntityKey(); final Object identifier = entityKey.getIdentifier(); Object loaded = null; if ( canReadFromCache && session.isEventSource() ) { - final EventSource eventSource = (EventSource) session; + final var eventSource = (EventSource) session; loaded = eventSource.loadFromSecondLevelCache( this, entityKey, entity, LockMode.NONE ); } if ( loaded == null ) { - final LockOptions lockOptions = new LockOptions(); + final var lockOptions = new LockOptions(); loaded = determineLoaderToUse( session, lockOptions ).load( identifier, entity, lockOptions, session ); } if ( loaded == null ) { - final PersistenceContext persistenceContext = session.getPersistenceContext(); + final var persistenceContext = session.getPersistenceContext(); persistenceContext.removeEntry( entity ); persistenceContext.removeEntity( entityKey ); factory.getEntityNotFoundDelegate().handleEntityNotFound( entityKey.getEntityName(), identifier ); } - final LazyAttributeLoadingInterceptor interceptor = - enhancementMetadata.injectInterceptor( entity, identifier, session ); + final var interceptor = enhancementMetadata.injectInterceptor( entity, identifier, session ); final Object value; if ( nameOfAttributeBeingAccessed == null ) { @@ -3637,7 +3620,7 @@ public void registerAffectingFetchProfile(String fetchProfileName) { @Override public boolean isAffectedByEntityGraph(LoadQueryInfluencers loadQueryInfluencers) { - final RootGraphImplementor graph = loadQueryInfluencers.getEffectiveEntityGraph().getGraph(); + final var graph = loadQueryInfluencers.getEffectiveEntityGraph().getGraph(); return graph != null && graph.appliesTo( getFactory().getJpaMetamodel().entity( getEntityName() ) ); } @@ -3682,8 +3665,8 @@ public boolean isAffectedByEnabledFilters( @Override public int[] findDirty(Object[] currentState, Object[] previousState, Object entity, SharedSessionContractImplementor session) throws HibernateException { - int[] props = DirtyHelper.findDirty( - entityMetamodel.getDirtyCheckablePropertyTypes(), + final int[] props = DirtyHelper.findDirty( + getDirtyCheckablePropertyTypes(), currentState, previousState, propertyColumnUpdateable, @@ -3713,7 +3696,7 @@ public int[] findDirty(Object[] currentState, Object[] previousState, Object ent public int[] findModified(Object[] old, Object[] current, Object entity, SharedSessionContractImplementor session) throws HibernateException { final int[] modified = DirtyHelper.findModified( - entityMetamodel.getProperties(), + getProperties(), current, old, propertyColumnUpdateable, @@ -3759,7 +3742,7 @@ private Dialect getDialect() { @Override public EntityMetamodel getEntityMetamodel() { - return entityMetamodel; + return this; } @Override @@ -3806,7 +3789,7 @@ public NaturalIdDataAccess getNaturalIdCacheAccessStrategy() { // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Override public final String getEntityName() { - return entityMetamodel.getName(); + return getName(); } @Override @@ -3814,72 +3797,27 @@ public final String getEntityName() { return jpaEntityName; } - @Override - public boolean isInherited() { - return entityMetamodel.isInherited(); - } - - @Override - public boolean hasCascades() { - return entityMetamodel.hasCascades(); - } - - @Override - public boolean hasToOnes() { - return entityMetamodel.hasToOnes(); - } - - @Override - public boolean hasCascadePersist() { - return entityMetamodel.hasCascadePersist(); - } - - @Override - public boolean hasCascadeDelete() { - return entityMetamodel.hasCascadeDelete(); - } - - @Override - public boolean hasOwnedCollections() { - return entityMetamodel.hasOwnedCollections(); - } - @Override public boolean hasIdentifierProperty() { - return !entityMetamodel.getIdentifierProperty().isVirtual(); + return !getIdentifierProperty().isVirtual(); } @Override public BasicType getVersionType() { - final var versionProperty = entityMetamodel.getVersionProperty(); + final var versionProperty = getVersionProperty(); return versionProperty == null ? null : (BasicType) versionProperty.getType(); } - @Override - public int getVersionProperty() { - return entityMetamodel.getVersionPropertyIndex(); - } - - @Override - public boolean isVersioned() { - return entityMetamodel.isVersioned(); - } - @Override public boolean isIdentifierAssignedByInsert() { - return entityMetamodel.getIdentifierProperty().isIdentifierAssignedByInsert(); - } - - @Override - public boolean hasLazyProperties() { - return entityMetamodel.hasLazyProperties(); + return getIdentifierProperty().isIdentifierAssignedByInsert(); } @Override public void afterReassociate(Object entity, SharedSessionContractImplementor session) { final var metadata = getBytecodeEnhancementMetadata(); if ( metadata.isEnhancedForLazyLoading() ) { - final BytecodeLazyAttributeInterceptor interceptor = metadata.extractLazyInterceptor( entity ); + final var interceptor = metadata.extractLazyInterceptor( entity ); if ( interceptor == null ) { metadata.injectInterceptor( entity, getIdentifier( entity, session ), session ); } @@ -3893,8 +3831,8 @@ public void afterReassociate(Object entity, SharedSessionContractImplementor ses private void handleNaturalIdReattachment(Object entity, SharedSessionContractImplementor session) { if ( naturalIdMapping != null ) { if ( naturalIdMapping.isMutable() ) { - final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); - final NaturalIdResolutions naturalIdResolutions = persistenceContext.getNaturalIdResolutions(); + final var persistenceContext = session.getPersistenceContextInternal(); + final var naturalIdResolutions = persistenceContext.getNaturalIdResolutions(); final Object id = getIdentifier( entity, session ); // for reattachment of mutable natural-ids, we absolutely positively have to grab the snapshot from the @@ -3933,20 +3871,19 @@ public Boolean isTransient(Object entity, SharedSessionContractImplementor sessi final Boolean isUnsaved = versionMapping.getUnsavedStrategy().isUnsaved( version ); if ( isUnsaved != null ) { if ( isUnsaved ) { - final PersistenceContext persistenceContext; - if ( version == null - && ( persistenceContext = session.getPersistenceContext() ).hasLoadContext() - && !persistenceContext.getLoadContexts().isLoadingFinished() ) { - // check if we're currently loading this entity instance, the version - // will be null but the entity cannot be considered transient - final EntityHolder holder = - persistenceContext.getEntityHolder( new EntityKey( id, this ) ); - if ( holder != null && holder.isEventuallyInitialized() && holder.getEntity() == entity ) { - return false; + if ( version == null ) { + final var persistenceContext = session.getPersistenceContext(); + if ( persistenceContext.hasLoadContext() + && !persistenceContext.getLoadContexts().isLoadingFinished() ) { + // check if we're currently loading this entity instance, the version + // will be null, but the entity cannot be considered transient + final var holder = persistenceContext.getEntityHolder( new EntityKey( id, this ) ); + if ( holder != null && holder.isEventuallyInitialized() && holder.getEntity() == entity ) { + return false; + } } } - final Generator identifierGenerator = getGenerator(); - if ( identifierGenerator != null ) { + if ( getGenerator() != null ) { final Boolean unsaved = identifierMapping.getUnsavedStrategy().isUnsaved( id ); if ( unsaved != null && !unsaved ) { throw new PropertyValueException( @@ -3970,10 +3907,10 @@ public Boolean isTransient(Object entity, SharedSessionContractImplementor sessi // check to see if it is in the second-level cache if ( session.getCacheMode().isGetEnabled() && canReadFromCache() ) { - final var cache = getCacheAccessStrategy(); final Object cacheKey = - cache.generateCacheKey( id, this, session.getFactory(), session.getTenantIdentifier() ); - final Object cacheEntry = CacheHelper.fromSharedCache( session, cacheKey, this, getCacheAccessStrategy() ); + getCacheAccessStrategy() + .generateCacheKey( id, this, session.getFactory(), session.getTenantIdentifier() ); + final Object cacheEntry = fromSharedCache( session, cacheKey, this, getCacheAccessStrategy() ); if ( cacheEntry != null ) { return false; } @@ -3982,46 +3919,21 @@ public Boolean isTransient(Object entity, SharedSessionContractImplementor sessi return null; } - @Override - public boolean hasCollections() { - return entityMetamodel.hasCollections(); - } - - @Override - public boolean hasMutableProperties() { - return entityMetamodel.hasMutableProperties(); - } - - @Override - public boolean isMutable() { - return entityMetamodel.isMutable(); - } - - @Override - public boolean isAbstract() { - return entityMetamodel.isAbstract(); - } - - @Override - public boolean hasSubclasses() { - return entityMetamodel.hasSubclasses(); - } - @Override public boolean hasProxy() { // skip proxy instantiation if entity is bytecode enhanced - return entityMetamodel.isLazy() + return isLazy() && !getBytecodeEnhancementMetadata().isEnhancedForLazyLoading(); } @Override @Deprecated public IdentifierGenerator getIdentifierGenerator() throws HibernateException { - return entityMetamodel.getIdentifierProperty().getIdentifierGenerator(); + return getIdentifierProperty().getIdentifierGenerator(); } @Override public Generator getGenerator() { - return entityMetamodel.getIdentifierProperty().getGenerator(); + return getIdentifierProperty().getGenerator(); } @Override @@ -4031,17 +3943,12 @@ public BeforeExecutionGenerator getVersionGenerator() { @Override public String getRootEntityName() { - return entityMetamodel.getRootName(); + return getRootName(); } @Override public String getMappedSuperclass() { - return entityMetamodel.getSuperclass(); - } - - @Override - public boolean isExplicitPolymorphism() { - return entityMetamodel.isExplicitPolymorphism(); + return getSuperclass(); } @Override @@ -4054,12 +3961,14 @@ public EntityMappingType resolveConcreteProxyTypeForId(Object id, SharedSessionC if ( !concreteProxy ) { return this; } - - EntityConcreteTypeLoader concreteTypeLoader = this.concreteTypeLoader; - if ( concreteTypeLoader == null ) { - this.concreteTypeLoader = concreteTypeLoader = new EntityConcreteTypeLoader( this, session.getFactory() ); + else { + var concreteTypeLoader = this.concreteTypeLoader; + if ( concreteTypeLoader == null ) { + this.concreteTypeLoader = concreteTypeLoader = + new EntityConcreteTypeLoader( this, session.getFactory() ); + } + return concreteTypeLoader.getConcreteType( id, session ); } - return concreteTypeLoader.getConcreteType( id, session ); } /** @@ -4082,11 +3991,11 @@ public Type getPropertyType(String propertyName) throws MappingException { @Override public boolean isSelectBeforeUpdateRequired() { - return entityMetamodel.isSelectBeforeUpdate(); + return isSelectBeforeUpdate(); } public final OptimisticLockStyle optimisticLockStyle() { - return entityMetamodel.getOptimisticLockStyle(); + return getOptimisticLockStyle(); } @Override @@ -4097,7 +4006,7 @@ public Object createProxy(Object id, SharedSessionContractImplementor session) t @Override public String toString() { return unqualify( getClass().getName() ) - + '(' + entityMetamodel.getName() + ')'; + + '(' + getName() + ')'; } @Override @@ -4107,12 +4016,22 @@ public boolean isInstrumented() { @Override public boolean hasInsertGeneratedProperties() { - return entityMetamodel.hasInsertGeneratedValues(); + return hasInsertGeneratedValues(); } @Override public boolean hasUpdateGeneratedProperties() { - return entityMetamodel.hasUpdateGeneratedValues(); + return hasUpdateGeneratedValues(); + } + + @Override + public boolean hasPreInsertGeneratedProperties() { + return hasPreInsertGeneratedValues(); + } + + @Override + public boolean hasPreUpdateGeneratedProperties() { + return hasPreUpdateGeneratedValues(); } @Override @@ -4122,18 +4041,18 @@ public boolean isVersionPropertyGenerated() { } private Generator versionPropertyGenerator() { - return getEntityMetamodel().getGenerators()[ getVersionProperty() ]; + return getGenerators()[ this.getVersionPropertyIndex() ]; } public boolean isVersionGeneratedOnExecution() { - final Generator strategy = versionPropertyGenerator(); + final var strategy = versionPropertyGenerator(); return strategy != null && strategy.generatesSometimes() && strategy.generatedOnExecution(); } public boolean isVersionGeneratedBeforeExecution() { - final Generator strategy = versionPropertyGenerator(); + final var strategy = versionPropertyGenerator(); return strategy != null && strategy.generatesSometimes() && !strategy.generatedOnExecution(); @@ -4153,54 +4072,14 @@ && getRepresentationStrategy().getMode() == POJO ) { } } - @Override - public String[] getPropertyNames() { - return entityMetamodel.getPropertyNames(); - } - - @Override - public Type[] getPropertyTypes() { - return entityMetamodel.getPropertyTypes(); - } - - @Override - public boolean[] getPropertyLaziness() { - return entityMetamodel.getPropertyLaziness(); - } - - @Override - public boolean[] getPropertyUpdateability() { - return entityMetamodel.getPropertyUpdateability(); - } - - @Override - public boolean[] getPropertyCheckability() { - return entityMetamodel.getPropertyCheckability(); - } - @Override public boolean[] getNonLazyPropertyUpdateability() { - return entityMetamodel.getNonlazyPropertyUpdateability(); - } - - @Override - public boolean[] getPropertyInsertability() { - return entityMetamodel.getPropertyInsertability(); - } - - @Override - public boolean[] getPropertyNullability() { - return entityMetamodel.getPropertyNullability(); - } - - @Override - public boolean[] getPropertyVersionability() { - return entityMetamodel.getPropertyVersionability(); + return getNonlazyPropertyUpdateability(); } @Override public CascadeStyle[] getPropertyCascadeStyles() { - return entityMetamodel.getCascadeStyles(); + return getCascadeStyles(); } @Override @@ -4215,7 +4094,7 @@ public final Class getMappedClass() { @Override public Class getConcreteProxyClass() { - final JavaType proxyJavaType = getRepresentationStrategy().getProxyJavaType(); + final var proxyJavaType = getRepresentationStrategy().getProxyJavaType(); return proxyJavaType != null ? proxyJavaType.getJavaTypeClass() : javaType.getJavaTypeClass(); } @@ -4225,9 +4104,9 @@ public void setPropertyValues(Object object, Object[] values) { accessOptimizer.setPropertyValues( object, values ); } else { - final AttributeMappingsList attributeMappings = getAttributeMappings(); + final int size = getAttributeMappings().size(); if ( getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) { - for ( int i = 0; i < attributeMappings.size(); i++ ) { + for ( int i = 0; i < size; i++ ) { final Object value = values[i]; if ( value != UNFETCHED_PROPERTY ) { setterCache[i].set( object, value ); @@ -4235,7 +4114,7 @@ public void setPropertyValues(Object object, Object[] values) { } } else { - for ( int i = 0; i < attributeMappings.size(); i++ ) { + for ( int i = 0; i < size; i++ ) { setterCache[i].set( object, values[i] ); } } @@ -4254,12 +4133,12 @@ public Object[] getPropertyValues(Object object) { } else { final var enhancementMetadata = getBytecodeEnhancementMetadata(); - final AttributeMappingsList attributeMappings = getAttributeMappings(); + final var attributeMappings = getAttributeMappings(); final Object[] values = new Object[attributeMappings.size()]; if ( enhancementMetadata.isEnhancedForLazyLoading() ) { final var lazyAttributesMetadata = enhancementMetadata.getLazyAttributesMetadata(); for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); + final var attributeMapping = attributeMappings.get( i ); if ( !lazyAttributesMetadata.isLazyAttribute( attributeMapping.getAttributeName() ) || enhancementMetadata.isAttributeLoaded( object, attributeMapping.getAttributeName() ) ) { values[i] = getterCache[i].get( object ); @@ -4285,50 +4164,49 @@ public Object getPropertyValue(Object object, int i) { } @Override - public Object getPropertyValue(Object object, String propertyName) { - final int dotIndex = propertyName.indexOf( '.' ); - final String basePropertyName = dotIndex == -1 - ? propertyName - : propertyName.substring( 0, dotIndex ); - final AttributeMapping attributeMapping = findAttributeMapping( basePropertyName ); - ManagedMappingType baseValueType = null; - Object baseValue = null; + public Object getPropertyValue(Object object, String path) { + final String basePropertyName = root( path ); + final boolean isBasePath = basePropertyName.length() == path.length(); + final var attributeMapping = findAttributeMapping( basePropertyName ); + final Object baseValue; + final MappingType baseValueType; if ( attributeMapping != null ) { - baseValue = getterCache[attributeMapping.getStateArrayPosition()].get( object ); - if ( dotIndex != -1 ) { - baseValueType = (ManagedMappingType) attributeMapping.getMappedType(); - } + baseValue = getterCache[ attributeMapping.getStateArrayPosition() ].get( object ); + baseValueType = attributeMapping.getMappedType(); } else if ( identifierMapping instanceof NonAggregatedIdentifierMapping nonAggregatedIdentifierMapping ) { - final AttributeMapping mapping = - nonAggregatedIdentifierMapping.findSubPart( propertyName, null ) + final var mapping = + nonAggregatedIdentifierMapping.findSubPart( path, null ) .asAttributeMapping(); - if ( mapping != null ) { - baseValue = mapping.getValue( object ); - if ( dotIndex != -1 ) { - baseValueType = (ManagedMappingType) mapping.getMappedType(); - } - } + baseValue = mapping == null ? null : mapping.getValue( object ); + baseValueType = mapping == null ? null : mapping.getMappedType(); + } + else { + baseValue = null; + baseValueType = null; } - return getPropertyValue( baseValue, baseValueType, propertyName, dotIndex ); + return isBasePath + ? baseValue + : getPropertyValue( baseValue, (ManagedMappingType) baseValueType, path, basePropertyName ); } private Object getPropertyValue( Object baseValue, ManagedMappingType baseValueType, - String propertyName, - int dotIndex) { + String path, + String prefix) { if ( baseValueType == null ) { + // TODO: is this necessary? Should it be an exception instead? return baseValue; } else { - final int nextDotIndex = propertyName.indexOf( '.', dotIndex + 1 ); - final int endIndex = nextDotIndex == -1 ? propertyName.length() : nextDotIndex; - final AttributeMapping attributeMapping = - baseValueType.findAttributeMapping( propertyName.substring( dotIndex + 1, endIndex ) ); - baseValue = attributeMapping.getValue( baseValue ); - baseValueType = nextDotIndex == -1 ? null : (ManagedMappingType) attributeMapping.getMappedType(); - return getPropertyValue( baseValue, baseValueType, propertyName, nextDotIndex ); + final int afterDot = prefix.length() + 1; + final int nextDotIndex = path.indexOf( '.', afterDot ); + final String pathSoFar = nextDotIndex < 0 ? path : path.substring( 0, nextDotIndex ); + final var attributeMapping = baseValueType.findAttributeMapping( pathSoFar.substring( afterDot ) ); + final var value = attributeMapping.getValue( baseValue ); + final var type = nextDotIndex < 0 ? null : (ManagedMappingType) attributeMapping.getMappedType(); + return getPropertyValue( value, type, path, pathSoFar ); } } @@ -4349,8 +4227,9 @@ public void setIdentifier(Object entity, Object id, SharedSessionContractImpleme @Override public Object getVersion(Object object) { - return getVersionMapping() == null ? null - : getVersionMapping().getVersionAttribute().getPropertyAccess().getGetter().get( object ); + final var versionMapping = getVersionMapping(); + return versionMapping == null ? null + : versionMapping.getVersionAttribute().getPropertyAccess().getGetter().get( object ); } @Override @@ -4413,8 +4292,8 @@ && hasSubclasses() && !getRepresentationStrategy().getInstantiator().isSameClass( instance ) ) { // todo (6.0) : this previously used `org.hibernate.tuple.entity.EntityTuplizer#determineConcreteSubclassEntityName` // - we may need something similar here... - for ( EntityMappingType subclassMappingType : subclassMappingTypes.values() ) { - final EntityPersister persister = subclassMappingType.getEntityPersister(); + for ( var subclassMappingType : subclassMappingTypes.values() ) { + final var persister = subclassMappingType.getEntityPersister(); if ( persister.getRepresentationStrategy().getInstantiator().isSameClass( instance ) ) { return persister; } @@ -4428,16 +4307,12 @@ public boolean hasMultipleTables() { return false; } - public int getPropertySpan() { - return entityMetamodel.getPropertySpan(); - } - @Override public Object[] getPropertyValuesToInsert( Object entity, Map mergeMap, SharedSessionContractImplementor session) - throws HibernateException { + throws HibernateException { if ( shouldGetAllProperties( entity ) && accessOptimizer != null ) { return accessOptimizer.getPropertyValues( entity ); } @@ -4472,7 +4347,7 @@ public void processInsertGeneratedProperties( protected List initInsertGeneratedProperties(List generatedAttributes) { final int originalSize = generatedAttributes.size(); final List generatedBasicAttributes = new ArrayList<>( originalSize ); - for ( AttributeMapping generatedAttribute : generatedAttributes ) { + for ( var generatedAttribute : generatedAttributes ) { // todo (7.0) : support non selectable mappings? Component, ToOneAttributeMapping, ... if ( generatedAttribute.asBasicValuedModelPart() != null && generatedAttribute.getContainingTableExpression().equals( getRootTableName() ) ) { @@ -4510,7 +4385,7 @@ public void processUpdateGeneratedProperties( protected List initUpdateGeneratedProperties(List generatedAttributes) { final int originalSize = generatedAttributes.size(); final List generatedBasicAttributes = new ArrayList<>( originalSize ); - for ( AttributeMapping generatedAttribute : generatedAttributes ) { + for ( var generatedAttribute : generatedAttributes ) { if ( generatedAttribute instanceof SelectableMapping selectableMapping && selectableMapping.getContainingTableExpression().equals( getSubclassTableName( 0 ) ) ) { generatedBasicAttributes.add( generatedAttribute ); @@ -4528,12 +4403,12 @@ public List getUpdateGeneratedProperties() { @Override public String getIdentifierPropertyName() { - return entityMetamodel.getIdentifierProperty().getName(); + return getIdentifierProperty().getName(); } @Override public Type getIdentifierType() { - return entityMetamodel.getIdentifierProperty().getType(); + return getIdentifierProperty().getType(); } @Override @@ -4546,11 +4421,6 @@ public boolean hasCollectionNotReferencingPK() { return hasCollectionNotReferencingPK; } - @Override - public int[] getNaturalIdentifierProperties() { - return entityMetamodel.getNaturalIdentifierProperties(); - } - protected void verifyHasNaturalId() { if ( ! hasNaturalIdentifier() ) { throw new HibernateException( "Entity does not define a natural id : " + getEntityName() ); @@ -4598,11 +4468,6 @@ public Object loadEntityIdByNaturalId( return getNaturalIdLoader().resolveNaturalIdToId( naturalIdValues, session ); } - @Override - public boolean hasNaturalIdentifier() { - return entityMetamodel.hasNaturalIdentifier(); - } - public static int getTableId(String tableName, String[] tables) { for ( int j = 0; j < tables.length; j++ ) { if ( tableName.equalsIgnoreCase( tables[j] ) ) { @@ -4622,11 +4487,6 @@ public BytecodeEnhancementMetadata getInstrumentationMetadata() { return getBytecodeEnhancementMetadata(); } - @Override - public final BytecodeEnhancementMetadata getBytecodeEnhancementMetadata() { - return entityMetamodel.getBytecodeEnhancementMetadata(); - } - @Override public String getTableNameForColumn(String columnName) { return getTableName( determineTableNumberForColumn( columnName ) ); @@ -4777,25 +4637,25 @@ private void handleSubtypeMappings(MappingModelCreationProcess creationProcess) } private static ReflectionOptimizer.AccessOptimizer accessOptimizer(EntityRepresentationStrategy strategy) { - final ReflectionOptimizer reflectionOptimizer = strategy.getReflectionOptimizer(); + final var reflectionOptimizer = strategy.getReflectionOptimizer(); return reflectionOptimizer == null ? null : reflectionOptimizer.getAccessOptimizer(); } private void prepareMappings(MappingModelCreationProcess creationProcess) { - final PersistentClass bootEntityDescriptor = + final var persistentClass = creationProcess.getCreationContext().getBootModel() .getEntityBinding( getEntityName() ); - initializeSpecialAttributeMappings( creationProcess, bootEntityDescriptor ); - versionGenerator = createVersionGenerator( entityMetamodel, versionMapping ); - buildDeclaredAttributeMappings( creationProcess, bootEntityDescriptor ); + initializeSpecialAttributeMappings( creationProcess, persistentClass ); + versionGenerator = createVersionGenerator( this, versionMapping ); + buildDeclaredAttributeMappings( creationProcess, persistentClass ); getAttributeMappings(); - initializeNaturalIdMapping( creationProcess, bootEntityDescriptor ); + initializeNaturalIdMapping( creationProcess, persistentClass ); } private void initializeSpecialAttributeMappings (MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { if ( superMappingType != null ) { - ((InFlightEntityMappingType) superMappingType).prepareMappingModel( creationProcess ); + ( (InFlightEntityMappingType) superMappingType ).prepareMappingModel( creationProcess ); if ( shouldProcessSuperMapping() ) { inheritSupertypeSpecialAttributeMappings(); } @@ -4819,14 +4679,14 @@ private void inheritSupertypeSpecialAttributeMappings() { private void buildDeclaredAttributeMappings (MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { + final var properties = getProperties(); + final var mappingsBuilder = AttributeMappingsMap.builder(); int stateArrayPosition = getStateArrayInitialPosition( creationProcess ); - final NonIdentifierAttribute[] properties = entityMetamodel.getProperties(); - final AttributeMappingsMap.Builder mappingsBuilder = AttributeMappingsMap.builder(); int fetchableIndex = getFetchableIndexOffset(); - for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { - final NonIdentifierAttribute runtimeAttributeDefinition = properties[i]; + for ( int i = 0; i < getPropertySpan(); i++ ) { + final var runtimeAttributeDefinition = properties[i]; final String attributeName = runtimeAttributeDefinition.getName(); - final Property bootProperty = bootEntityDescriptor.getProperty( attributeName ); + final var bootProperty = bootEntityDescriptor.getProperty( attributeName ); if ( superMappingType == null || superMappingType.findAttributeMapping( bootProperty.getName() ) == null ) { mappingsBuilder.put( @@ -4848,7 +4708,7 @@ private void inheritSupertypeSpecialAttributeMappings() { private static BeforeExecutionGenerator createVersionGenerator (EntityMetamodel currentEntityMetamodel, EntityVersionMapping versionMapping) { if ( currentEntityMetamodel.isVersioned() ) { - final BeforeExecutionGenerator generator = currentEntityMetamodel.getVersionGenerator(); + final var generator = currentEntityMetamodel.getVersionGenerator(); // need to do this here because EntityMetamodel doesn't have the EntityVersionMapping :-( return generator == null ? new VersionGeneration( versionMapping ) : generator; } @@ -4903,10 +4763,10 @@ private boolean isSubselect() { } private boolean generatorNeedsMultiTableInsert() { - final Generator generator = getGenerator(); + final var generator = getGenerator(); if ( generator instanceof BulkInsertionCapableIdentifierGenerator && generator instanceof OptimizableGenerator optimizableGenerator ) { - final Optimizer optimizer = optimizableGenerator.getOptimizer(); + final var optimizer = optimizableGenerator.getOptimizer(); return optimizer != null && optimizer.getIncrementSize() > 1; } else { @@ -4916,9 +4776,9 @@ private boolean generatorNeedsMultiTableInsert() { private int getFetchableIndexOffset() { if ( superMappingType != null ) { - final EntityMappingType rootEntityDescriptor = getRootEntityDescriptor(); + final var rootEntityDescriptor = getRootEntityDescriptor(); int offset = rootEntityDescriptor.getNumberOfDeclaredAttributeMappings(); - for ( EntityMappingType subMappingType : rootEntityDescriptor.getSubMappingTypes() ) { + for ( var subMappingType : rootEntityDescriptor.getSubMappingTypes() ) { if ( subMappingType == this ) { break; } @@ -4926,9 +4786,9 @@ private int getFetchableIndexOffset() { // because calling `subMappingType.getNumberOfDeclaredAttributeMappings()` at this point // may produce wrong results because subMappingType might not have completed prepareMappingModel yet final int propertySpan = - subMappingType.getEntityPersister().getEntityMetamodel().getPropertySpan(); + subMappingType.getEntityPersister().getPropertySpan(); final int superPropertySpan = - subMappingType.getSuperMappingType().getEntityPersister().getEntityMetamodel().getPropertySpan(); + subMappingType.getSuperMappingType().getEntityPersister().getPropertySpan(); final int numberOfDeclaredAttributeMappings = propertySpan - superPropertySpan; offset += numberOfDeclaredAttributeMappings; } @@ -4938,25 +4798,21 @@ private int getFetchableIndexOffset() { } private void prepareMappingModel(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { - final EntityInstantiator instantiator = getRepresentationStrategy().getInstantiator(); + final var instantiator = getRepresentationStrategy().getInstantiator(); final Supplier instantiate = instantiator.canBeInstantiated() ? instantiator::instantiate : null; - identifierMapping = creationProcess.processSubPart( EntityIdentifierMapping.ID_ROLE_NAME, - (role, process) -> generateIdentifierMapping( instantiate, bootEntityDescriptor, process ) ); + identifierMapping = + creationProcess.processSubPart( EntityIdentifierMapping.ID_ROLE_NAME, + (role, process) -> generateIdentifierMapping( instantiate, bootEntityDescriptor, process ) ); versionMapping = generateVersionMapping( instantiate, bootEntityDescriptor, creationProcess ); rowIdMapping = rowIdName == null ? null : creationProcess.processSubPart( rowIdName, (role, process) -> new EntityRowIdMappingImpl( rowIdName, getTableName(), this ) ); discriminatorMapping = generateDiscriminatorMapping( bootEntityDescriptor ); - softDeleteMapping = resolveSoftDeleteMapping( - this, - bootEntityDescriptor.getRootClass(), - getIdentifierTableName(), - creationProcess - ); - if ( softDeleteMapping != null ) { - if ( bootEntityDescriptor.getRootClass().getCustomSQLDelete() != null ) { - throw new UnsupportedMappingException( "Entity may not define both @SoftDelete and @SQLDelete" ); - } + final var rootClass = bootEntityDescriptor.getRootClass(); + softDeleteMapping = + resolveSoftDeleteMapping( this, rootClass, getIdentifierTableName(), creationProcess ); + if ( softDeleteMapping != null && rootClass.getCustomSQLDelete() != null ) { + throw new UnsupportedMappingException( "Entity may not define both @SoftDelete and @SQLDelete" ); } } @@ -4978,14 +4834,13 @@ else if ( bootEntityDescriptor.hasNaturalId() ) { //noinspection AssertWithSideEffects assert bootEntityDescriptor.hasNaturalId(); - final int[] naturalIdAttributeIndexes = entityMetamodel.getNaturalIdentifierProperties(); + final int[] naturalIdAttributeIndexes = getNaturalIdentifierProperties(); assert naturalIdAttributeIndexes.length > 0; if ( naturalIdAttributeIndexes.length == 1 ) { - final String propertyName = entityMetamodel.getPropertyNames()[ naturalIdAttributeIndexes[ 0 ] ]; - final AttributeMapping attributeMapping = findAttributeMapping( propertyName ); - final SingularAttributeMapping singularAttributeMapping = (SingularAttributeMapping) attributeMapping; - return new SimpleNaturalIdMapping( singularAttributeMapping, this, creationProcess ); + final String propertyName = getPropertyNames()[ naturalIdAttributeIndexes[ 0 ] ]; + final var attributeMapping = (SingularAttributeMapping) findAttributeMapping( propertyName ); + return new SimpleNaturalIdMapping( attributeMapping, this, creationProcess ); } // collect the names of the attributes making up the natural-id. @@ -4999,7 +4854,7 @@ else if ( bootEntityDescriptor.hasNaturalId() ) { final List collectedAttrMappings = new ArrayList<>(); for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); + final var attributeMapping = attributeMappings.get( i ); if ( attributeNames.contains( attributeMapping.getAttributeName() ) ) { collectedAttrMappings.add( (SingularAttributeMapping) attributeMapping ); } @@ -5016,26 +4871,24 @@ protected static SqmMultiTableMutationStrategy interpretSqmMultiTableStrategy( AbstractEntityPersister entityMappingDescriptor, MappingModelCreationProcess creationProcess) { assert entityMappingDescriptor.hasMultipleTables(); - - final EntityMappingType superMappingType = entityMappingDescriptor.getSuperMappingType(); + final var superMappingType = entityMappingDescriptor.getSuperMappingType(); if ( superMappingType != null ) { - final SqmMultiTableMutationStrategy sqmMultiTableMutationStrategy = + final var sqmMultiTableMutationStrategy = superMappingType.getSqmMultiTableMutationStrategy(); if ( sqmMultiTableMutationStrategy != null ) { return sqmMultiTableMutationStrategy; } } - - final ServiceRegistry serviceRegistry = creationProcess.getCreationContext().getServiceRegistry(); - return serviceRegistry.requireService( SqmMultiTableMutationStrategyProvider.class ) + return creationProcess.getCreationContext().getServiceRegistry() + .requireService( SqmMultiTableMutationStrategyProvider.class ) .createMutationStrategy( entityMappingDescriptor, creationProcess ); } protected static SqmMultiTableInsertStrategy interpretSqmMultiTableInsertStrategy( AbstractEntityPersister entityMappingDescriptor, MappingModelCreationProcess creationProcess) { - final ServiceRegistry serviceRegistry = creationProcess.getCreationContext().getServiceRegistry(); - return serviceRegistry.requireService( SqmMultiTableMutationStrategyProvider.class ) + return creationProcess.getCreationContext().getServiceRegistry() + .requireService( SqmMultiTableMutationStrategyProvider.class ) .createInsertStrategy( entityMappingDescriptor, creationProcess ); } @@ -5076,10 +4929,13 @@ protected EntityDiscriminatorMapping generateDiscriminatorMapping(PersistentClas final Integer arrayLength; final Integer precision; final Integer scale; - if ( getDiscriminatorFormulaTemplate() == null ) { - final Column column = bootEntityDescriptor.getDiscriminator() == null - ? null - : bootEntityDescriptor.getDiscriminator().getColumns().get( 0 ); + final String discriminatorFormulaTemplate = getDiscriminatorFormulaTemplate(); + if ( discriminatorFormulaTemplate == null ) { + final var discriminator = bootEntityDescriptor.getDiscriminator(); + final Column column = + discriminator == null + ? null + : discriminator.getColumns().get( 0 ); discriminatorColumnExpression = getDiscriminatorColumnReaders(); if ( column == null ) { columnDefinition = null; @@ -5097,7 +4953,7 @@ protected EntityDiscriminatorMapping generateDiscriminatorMapping(PersistentClas } } else { - discriminatorColumnExpression = getDiscriminatorFormulaTemplate(); + discriminatorColumnExpression = discriminatorFormulaTemplate; columnDefinition = null; length = null; arrayLength = null; @@ -5109,7 +4965,7 @@ protected EntityDiscriminatorMapping generateDiscriminatorMapping(PersistentClas discriminatorColumnExpression, getTableName(), discriminatorColumnExpression, - getDiscriminatorFormulaTemplate() != null, + discriminatorFormulaTemplate != null, isPhysicalDiscriminator(), false, columnDefinition, @@ -5135,7 +4991,7 @@ protected EntityVersionMapping generateVersionMapping( } else { return creationProcess.processSubPart( - getPropertyNames()[getVersionProperty()], + getPropertyNames()[this.getVersionPropertyIndex()], (role, process) -> generateVersionMapping( this, templateInstanceCreator, @@ -5154,7 +5010,7 @@ protected boolean shouldProcessSuperMapping(){ public void linkWithSuperType(MappingModelCreationProcess creationProcess) { if ( getMappedSuperclass() != null ) { superMappingType = creationProcess.getEntityPersister( getMappedSuperclass() ); - final InFlightEntityMappingType inFlightEntityMappingType = (InFlightEntityMappingType) superMappingType; + final var inFlightEntityMappingType = (InFlightEntityMappingType) superMappingType; inFlightEntityMappingType.linkWithSubType(this, creationProcess); if ( subclassMappingTypes != null ) { subclassMappingTypes.values() @@ -5247,10 +5103,11 @@ protected EntityIdentifierMapping generateIdentifierMapping( final boolean encapsulated = !cidType.isEmbedded(); if ( encapsulated ) { // we have an `@EmbeddedId` - return MappingModelCreationHelper.buildEncapsulatedCompositeIdentifierMapping( + final var identifierProperty = bootEntityDescriptor.getIdentifierProperty(); + return buildEncapsulatedCompositeIdentifierMapping( this, - bootEntityDescriptor.getIdentifierProperty(), - bootEntityDescriptor.getIdentifierProperty().getName(), + identifierProperty, + identifierProperty.getName(), getTableName(), rootTableKeyColumnNames, cidType, @@ -5266,7 +5123,8 @@ protected EntityIdentifierMapping generateIdentifierMapping( final Integer arrayLength; final Integer precision; final Integer scale; - if ( bootEntityDescriptor.getIdentifier() == null ) { + final var identifier = bootEntityDescriptor.getIdentifier(); + if ( identifier == null ) { columnDefinition = null; length = null; arrayLength = null; @@ -5274,7 +5132,7 @@ protected EntityIdentifierMapping generateIdentifierMapping( scale = null; } else { - Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 ); + final Column column = identifier.getColumns().get( 0 ); columnDefinition = column.getSqlType(); length = column.getLength(); arrayLength = column.getArrayLength(); @@ -5282,11 +5140,12 @@ protected EntityIdentifierMapping generateIdentifierMapping( scale = column.getScale(); } - final Value value = bootEntityDescriptor.getIdentifierProperty().getValue(); + final var identifierProperty = bootEntityDescriptor.getIdentifierProperty(); + final var value = identifierProperty.getValue(); return new BasicEntityIdentifierMappingImpl( this, templateInstanceCreator, - bootEntityDescriptor.getIdentifierProperty().getName(), + identifierProperty.getName(), getTableName(), rootTableKeyColumnNames[0], columnDefinition, @@ -5304,7 +5163,7 @@ protected EntityIdentifierMapping generateIdentifierMapping( protected EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMapping( MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { - return MappingModelCreationHelper.buildNonEncapsulatedCompositeIdentifierMapping( + return buildNonEncapsulatedCompositeIdentifierMapping( this, getTableName(), getRootTableKeyColumnNames(), @@ -5323,12 +5182,12 @@ protected static EntityVersionMapping generateVersionMapping( Supplier templateInstanceCreator, PersistentClass bootModelRootEntityDescriptor, MappingModelCreationProcess creationProcess) { - final Property versionProperty = bootModelRootEntityDescriptor.getVersion(); - final BasicValue bootModelVersionValue = (BasicValue) versionProperty.getValue(); - final BasicValue.Resolution basicTypeResolution = bootModelVersionValue.resolve(); + final var versionProperty = bootModelRootEntityDescriptor.getVersion(); + final var bootModelVersionValue = (BasicValue) versionProperty.getValue(); + final var basicTypeResolution = bootModelVersionValue.resolve(); - final Column column = (Column) bootModelVersionValue.getColumn(); - final Dialect dialect = creationProcess.getCreationContext().getDialect(); + final var column = (Column) bootModelVersionValue.getColumn(); + final var dialect = creationProcess.getCreationContext().getDialect(); return new EntityVersionMappingImpl( bootModelRootEntityDescriptor.getRootClass(), @@ -5353,7 +5212,7 @@ protected AttributeMapping generateNonIdAttributeMapping( int stateArrayPosition, int fetchableIndex, MappingModelCreationProcess creationProcess) { - final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext(); + final var creationContext = creationProcess.getCreationContext(); final String attrName = tupleAttrDefinition.getName(); final Type attrType = tupleAttrDefinition.getType(); @@ -5363,12 +5222,12 @@ protected AttributeMapping generateNonIdAttributeMapping( final String tableExpression = getTableName( getPropertyTableNumbers()[propertyIndex] ); final String[] attrColumnNames = getPropertyColumnNames( propertyIndex ); - final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootProperty ); + final var propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootProperty ); - final Value value = bootProperty.getValue(); - if ( propertyIndex == getVersionProperty() ) { - Column column = value.getColumns().get( 0 ); - return MappingModelCreationHelper.buildBasicAttributeMapping( + final var value = bootProperty.getValue(); + if ( propertyIndex == this.getVersionPropertyIndex() ) { + final Column column = value.getColumns().get( 0 ); + return buildBasicAttributeMapping( attrName, getNavigableRole().append( bootProperty.getName() ), stateArrayPosition, @@ -5429,28 +5288,30 @@ protected AttributeMapping generateNonIdAttributeMapping( nullable = column.isNullable(); } else { - final BasicValue basicBootValue = (BasicValue) value; + final var basicBootValue = (BasicValue) value; if ( attrColumnNames[ 0 ] != null ) { attrColumnExpression = attrColumnNames[ 0 ]; isAttrColumnExpressionFormula = false; - final List selectables = basicBootValue.getSelectables(); + final var selectables = basicBootValue.getSelectables(); assert !selectables.isEmpty(); - final Selectable selectable = selectables.get(0); + final var selectable = selectables.get(0); - assert attrColumnExpression.equals( selectable.getText( creationContext.getDialect() ) ); + final var dialect = creationContext.getDialect(); + + assert attrColumnExpression.equals( selectable.getText( dialect ) ); customReadExpr = selectable.getTemplate( - creationContext.getDialect(), + dialect, creationContext.getTypeConfiguration() ); customWriteExpr = selectable.getWriteExpr( (JdbcMapping) attrType, - creationContext.getDialect(), + dialect, creationContext.getBootModel() ); - Column column = value.getColumns().get( 0 ); + final var column = value.getColumns().get( 0 ); columnDefinition = column.getSqlType(); length = column.getLength(); arrayLength = column.getArrayLength(); @@ -5459,7 +5320,7 @@ protected AttributeMapping generateNonIdAttributeMapping( scale = column.getScale(); nullable = column.isNullable(); isLob = column.isSqlTypeLob( creationContext.getMetadata() ); - MappingModelCreationHelper.resolveAggregateColumnBasicType( creationProcess, role, column ); + resolveAggregateColumnBasicType( creationProcess, role, column ); } else { final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[ propertyIndex ]; @@ -5478,7 +5339,7 @@ protected AttributeMapping generateNonIdAttributeMapping( } } - return MappingModelCreationHelper.buildBasicAttributeMapping( + return buildBasicAttributeMapping( attrName, role, stateArrayPosition, @@ -5512,8 +5373,9 @@ else if ( attrType instanceof AnyType anyType ) { creationContext.getTypeConfiguration().getJavaTypeRegistry() .getDescriptor( Object.class ); - final MutabilityPlan mutabilityPlan = new DiscriminatedAssociationAttributeMapping.MutabilityPlanImpl( anyType ); - final SimpleAttributeMetadata attributeMetadataAccess = new SimpleAttributeMetadata( + final MutabilityPlan mutabilityPlan = + new DiscriminatedAssociationAttributeMapping.MutabilityPlanImpl( anyType ); + final var attributeMetadataAccess = new SimpleAttributeMetadata( propertyAccess, mutabilityPlan, bootProperty.isOptional(), @@ -5539,11 +5401,13 @@ else if ( attrType instanceof AnyType anyType ) { ); } else if ( attrType instanceof CompositeType ) { - DependantValue dependantValue = null; - if ( bootProperty.getValue() instanceof DependantValue ) { - dependantValue = ( (DependantValue) bootProperty.getValue() ); + final DependantValue dependantValue; + if ( bootProperty.getValue() instanceof DependantValue depValue ) { + dependantValue = depValue; + } + else { + dependantValue = null; } - return buildEmbeddedAttributeMapping( attrName, stateArrayPosition, @@ -5724,20 +5588,20 @@ public AttributeMappingsList getAttributeMappings() { if ( attributeMappings == null ) { int sizeHint = declaredAttributeMappings.size(); sizeHint += (superMappingType == null ? 0 : superMappingType.getAttributeMappings().size() ); - ImmutableAttributeMappingList.Builder builder = new ImmutableAttributeMappingList.Builder( sizeHint ); + final var builder = new ImmutableAttributeMappingList.Builder( sizeHint ); if ( superMappingType != null ) { superMappingType.forEachAttributeMapping( builder::add ); } - for ( AttributeMapping am : declaredAttributeMappings.valueIterator() ) { + for ( var am : declaredAttributeMappings.valueIterator() ) { builder.add( am ); } attributeMappings = builder.build(); final Getter[] getters = new Getter[attributeMappings.size()]; final Setter[] setters = new Setter[attributeMappings.size()]; for ( int i = 0; i < attributeMappings.size(); i++ ) { - final PropertyAccess propertyAccess = attributeMappings.get( i ).getAttributeMetadata().getPropertyAccess(); + final var propertyAccess = attributeMappings.get( i ).getAttributeMetadata().getPropertyAccess(); getters[i] = propertyAccess.getGetter(); setters[i] = propertyAccess.getSetter(); } @@ -5756,7 +5620,7 @@ public AttributeMapping findDeclaredAttributeMapping(String name) { @Override public AttributeMapping findAttributeMapping(String name) { - final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name ); + final var declaredAttribute = declaredAttributeMappings.get( name ); if ( declaredAttribute != null ) { return declaredAttribute; } @@ -5775,17 +5639,19 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) { return discriminatorMapping; } - final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name ); + final var declaredAttribute = declaredAttributeMappings.get( name ); if ( declaredAttribute != null ) { return declaredAttribute; } if ( superMappingType != null ) { - final ModelPart superDefinedAttribute = superMappingType.findSubPart( name, superMappingType ); + final var superDefinedAttribute = + superMappingType.findSubPart( name, superMappingType ); if ( superDefinedAttribute != null ) { // Prefer the identifier mapping of the concrete class if ( superDefinedAttribute.isEntityIdentifierMapping() ) { - final ModelPart identifierModelPart = getIdentifierModelPart( name, treatTargetType ); + final var identifierModelPart = + getIdentifierModelPart( name, treatTargetType ); if ( identifierModelPart != null ) { return identifierModelPart; } @@ -5800,15 +5666,13 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) { } if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) { - for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) { - if ( ! treatTargetType.isTypeOrSuperType( subMappingType ) ) { - continue; - } - - final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType ); - - if ( subDefinedAttribute != null ) { - return subDefinedAttribute; + for ( var subMappingType : subclassMappingTypes.values() ) { + if ( treatTargetType.isTypeOrSuperType( subMappingType ) ) { + final var subDefinedAttribute = + subMappingType.findSubTypesSubPart( name, treatTargetType ); + if ( subDefinedAttribute != null ) { + return subDefinedAttribute; + } } } } @@ -5817,9 +5681,10 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) { if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) { ModelPart attribute = null; for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) { - final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType ); + final var subDefinedAttribute = + subMappingType.findSubTypesSubPart( name, treatTargetType ); if ( subDefinedAttribute != null ) { - if ( attribute != null && !MappingModelHelper.isCompatibleModelPart( attribute, subDefinedAttribute ) ) { + if ( attribute != null && !isCompatibleModelPart( attribute, subDefinedAttribute ) ) { throw new PathException( String.format( Locale.ROOT, @@ -5842,14 +5707,15 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) { } } - final ModelPart identifierModelPart = getIdentifierModelPart( name, treatTargetType ); + final var identifierModelPart = getIdentifierModelPart( name, treatTargetType ); if ( identifierModelPart != null ) { return identifierModelPart; } else { - for ( AttributeMapping attribute : declaredAttributeMappings.valueIterator() ) { - if ( attribute instanceof EmbeddableValuedModelPart part && attribute instanceof VirtualModelPart ) { - final ModelPart subPart = part.findSubPart( name, null ); + for ( var attribute : declaredAttributeMappings.valueIterator() ) { + if ( attribute instanceof EmbeddableValuedModelPart part + && attribute instanceof VirtualModelPart ) { + final var subPart = part.findSubPart( name, null ); if ( subPart != null ) { return subPart; } @@ -5861,14 +5727,15 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) { @Override public ModelPart findSubTypesSubPart(String name, EntityMappingType treatTargetType) { - final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name ); + final var declaredAttribute = declaredAttributeMappings.get( name ); if ( declaredAttribute != null ) { return declaredAttribute; } else { if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) { - for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) { - final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType ); + for ( var subMappingType : subclassMappingTypes.values() ) { + final var subDefinedAttribute = + subMappingType.findSubTypesSubPart( name, treatTargetType ); if ( subDefinedAttribute != null ) { return subDefinedAttribute; } @@ -5879,9 +5746,9 @@ public ModelPart findSubTypesSubPart(String name, EntityMappingType treatTargetT } private ModelPart getIdentifierModelPart(String name, EntityMappingType treatTargetType) { - final EntityIdentifierMapping identifierMapping = getIdentifierMappingForJoin(); + final var identifierMapping = getIdentifierMappingForJoin(); if ( identifierMapping instanceof final NonAggregatedIdentifierMapping mapping ) { - final ModelPart subPart = mapping.findSubPart( name, treatTargetType ); + final var subPart = mapping.findSubPart( name, treatTargetType ); if ( subPart != null ) { return subPart; } @@ -5897,7 +5764,7 @@ private ModelPart getIdentifierModelPart(String name, EntityMappingType treatTar private boolean isIdentifierReference(String name) { return EntityIdentifierMapping.ID_ROLE_NAME.equals( name ) || hasIdentifierProperty() && getIdentifierPropertyName().equals( name ) - || !entityMetamodel.hasNonIdentifierPropertyNamedId() && "id".equals( name ); + || !hasNonIdentifierPropertyNamedId() && "id".equals( name ); } @Override @@ -5964,9 +5831,9 @@ public void visitFetchables(IndexedConsumer fetchableConsumer if ( treatTargetType.isTypeOrSuperType( this ) ) { if ( subclassMappingTypes != null ) { int offset = attributeMappings.size(); - for ( EntityMappingType subtype : subclassMappingTypes.values() ) { - final AttributeMappingsMap declaredAttributeMappings = subtype.getDeclaredAttributeMappings(); - for ( AttributeMapping declaredAttributeMapping : declaredAttributeMappings.valueIterator() ) { + for ( var subtype : subclassMappingTypes.values() ) { + final var declaredAttributeMappings = subtype.getDeclaredAttributeMappings(); + for ( var declaredAttributeMapping : declaredAttributeMappings.valueIterator() ) { fetchableConsumer.accept( offset++, declaredAttributeMapping ); } } @@ -5995,7 +5862,7 @@ public void visitSuperTypeAttributeMappings(Consumer a public int forEachSelectable(int offset, SelectableConsumer selectableConsumer) { int span = 0; for ( int i = 0; i < attributeMappings.size(); i++ ) { - final AttributeMapping attributeMapping = attributeMappings.get( i ); + final var attributeMapping = attributeMappings.get( i ); span += attributeMapping.forEachSelectable( span + offset, selectableConsumer ); } return span; @@ -6029,7 +5896,7 @@ public Object disassemble(Object value, SharedSessionContractImplementor session if ( value == null ) { return null; } - final EntityIdentifierMapping identifierMapping = getIdentifierMapping(); + final var identifierMapping = getIdentifierMapping(); final Object identifier = identifierMapping.getIdentifier( value ); return identifierMapping.disassemble( identifier, session ); } @@ -6054,7 +5921,7 @@ public int forEachJdbcValue( Y y, JdbcValuesBiConsumer consumer, SharedSessionContractImplementor session) { - final EntityIdentifierMapping identifierMapping = getIdentifierMapping(); + final var identifierMapping = getIdentifierMapping(); final Object identifier = value == null ? null : identifierMapping.disassemble( identifierMapping.getIdentifier( value ), session ); return identifierMapping.forEachDisassembledJdbcValue( identifier, offset, x, y, consumer, session ); @@ -6105,8 +5972,6 @@ public boolean hasPartitionedSelectionMapping() { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - @Deprecated private final EntityMetamodel entityMetamodel; - @Deprecated private final String[] subclassColumnAliasClosure; @Deprecated private final String[] subclassFormulaAliasClosure; @Deprecated private final Map subclassPropertyAliases = new HashMap<>(); @@ -6154,7 +6019,7 @@ public String[] getSubclassPropertyColumnAliases(String propertyName, String suf internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosure() ); // aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id' - if ( !entityMetamodel.hasNonIdentifierPropertyNamedId() ) { + if ( !hasNonIdentifierPropertyNamedId() ) { subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() ); } @@ -6170,7 +6035,7 @@ public String[] getSubclassPropertyColumnAliases(String propertyName, String suf final String[] idAliases = getIdentifierAliases(); for ( int i = 0; i < idPropertyNames.length; i++ ) { - if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) { + if ( hasNonIdentifierPropertyNamedId() ) { subclassPropertyAliases.put( ENTITY_ID + "." + idPropertyNames[i], new String[] {idAliases[i]} @@ -6190,24 +6055,24 @@ public String[] getSubclassPropertyColumnAliases(String propertyName, String suf } } - if ( entityMetamodel.isPolymorphic() ) { + if ( isPolymorphic() ) { subclassPropertyAliases.put( ENTITY_CLASS, new String[] {getDiscriminatorAlias()} ); } } private void internalInitSubclassPropertyAliasesMap(String path, List properties) { - for (Property property : properties) { + for ( var property : properties ) { final String name = path == null ? property.getName() : path + "." + property.getName(); if ( property.isComposite() ) { - final Component component = (Component) property.getValue(); + final var component = (Component) property.getValue(); internalInitSubclassPropertyAliasesMap( name, component.getProperties() ); } final String[] aliases = new String[property.getColumnSpan()]; int l = 0; - final Dialect dialect = getDialect(); - for ( Selectable selectable: property.getSelectables() ) { + final var dialect = getDialect(); + for ( var selectable: property.getSelectables() ) { aliases[l] = selectable.getAlias( dialect, property.getValue().getTable() ); l++; } @@ -6227,7 +6092,7 @@ protected String getSqlWhereStringTableExpression(){ @Override public boolean managesColumns(String[] columnNames) { - for (String columnName : columnNames) { + for ( String columnName : columnNames ) { if ( !writesToColumn( columnName ) ) { return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index 68ff5ca85ece..1c9e2ace41a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -18,6 +18,7 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MappingException; +import org.hibernate.annotations.OnDeleteAction; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.cache.MutableCacheKeyBuilder; @@ -212,8 +213,31 @@ default String getImportedName() { * *@return The metamodel */ + @Deprecated(since = "7.2", forRemoval = true) EntityMetamodel getEntityMetamodel(); + boolean isPolymorphic(); + + boolean isDynamicUpdate(); + + boolean isDynamicInsert(); + + OnDeleteAction[] getPropertyOnDeleteActions(); + + Generator[] getGenerators(); + + boolean hasImmutableNaturalId(); + + boolean isNaturalIdentifierInsertGenerated(); + + boolean isLazy(); + + int getPropertySpan(); + + boolean hasPreInsertGeneratedProperties(); + + boolean hasPreUpdateGeneratedProperties(); + /** * Called from {@link EnhancementAsProxyLazinessInterceptor} to trigger load of * the entity's non-lazy state as well as the named attribute we are accessing @@ -496,7 +520,7 @@ default VersionJavaType getVersionJavaType() { * * @return The type of the version property; or -66, if not versioned. */ - int getVersionProperty(); + int getVersionPropertyIndex(); /** * Determine whether this entity defines a natural identifier. diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 002fd126e1d1..5410d56c1dfb 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Supplier; @@ -23,18 +22,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.DynamicFilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jdbc.Expectation; import org.hibernate.mapping.Column; -import org.hibernate.mapping.Join; -import org.hibernate.mapping.KeyValue; -import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.Selectable; -import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; -import org.hibernate.mapping.Value; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; @@ -54,17 +45,18 @@ import org.hibernate.sql.model.ast.builder.MutationGroupBuilder; import org.hibernate.sql.model.ast.builder.TableInsertBuilder; import org.hibernate.type.BasicType; -import org.hibernate.type.BasicTypeRegistry; import org.hibernate.type.CompositeType; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; -import org.hibernate.type.spi.TypeConfiguration; import org.jboss.logging.Logger; import static java.util.Collections.emptyMap; +import static org.hibernate.internal.util.collections.ArrayHelper.contains; +import static org.hibernate.internal.util.collections.ArrayHelper.join; import static org.hibernate.internal.util.collections.ArrayHelper.reverseFirst; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; +import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray; import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray; import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray; import static org.hibernate.internal.util.collections.CollectionHelper.linkedMapOfSize; @@ -161,18 +153,18 @@ public JoinedSubclassEntityPersister( final RuntimeModelCreationContext creationContext) throws HibernateException { super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext ); - final Dialect dialect = creationContext.getDialect(); - final TypeConfiguration typeConfiguration = creationContext.getTypeConfiguration(); - final BasicTypeRegistry basicTypeRegistry = typeConfiguration.getBasicTypeRegistry(); + final var dialect = creationContext.getDialect(); + final var typeConfiguration = creationContext.getTypeConfiguration(); + final var basicTypeRegistry = typeConfiguration.getBasicTypeRegistry(); // DISCRIMINATOR if ( persistentClass.isPolymorphic() ) { forceDiscriminator = persistentClass.isForceDiscriminator(); - final Value discriminatorMapping = persistentClass.getDiscriminator(); + final var discriminatorMapping = persistentClass.getDiscriminator(); if ( discriminatorMapping != null ) { log.tracef( "Encountered explicit discriminator mapping for joined inheritance" ); - final Selectable selectable = discriminatorMapping.getSelectables().get(0); + final var selectable = discriminatorMapping.getSelectables().get(0); if ( selectable instanceof Column column ) { explicitDiscriminatorColumnName = column.getQuotedName( dialect ); discriminatorAlias = column.getAlias( dialect, persistentClass.getRootTable() ); @@ -219,18 +211,18 @@ public JoinedSubclassEntityPersister( final ArrayList keyColumnReaders = new ArrayList<>(); final ArrayList keyColumnReaderTemplates = new ArrayList<>(); final ArrayList cascadeDeletes = new ArrayList<>(); - final List tableClosure = persistentClass.getTableClosure(); - final List keyClosure = persistentClass.getKeyClosure(); + final var tableClosure = persistentClass.getTableClosure(); + final var keyClosure = persistentClass.getKeyClosure(); for ( int i = 0; i < tableClosure.size() && i < keyClosure.size(); i++ ) { tableNames.add( determineTableName( tableClosure.get(i) ) ); - final KeyValue key = keyClosure.get(i); + final var key = keyClosure.get(i); final String[] keyCols = new String[idColumnSpan]; final String[] keyColReaders = new String[idColumnSpan]; final String[] keyColReaderTemplates = new String[idColumnSpan]; - final List columns = key.getColumns(); + final var columns = key.getColumns(); for ( int k = 0; k < idColumnSpan; k++ ) { - final Column column = columns.get(k); + final var column = columns.get(k); keyCols[k] = column.getQuotedName( dialect ); keyColReaders[k] = column.getReadExpr( dialect ); keyColReaderTemplates[k] = column.getTemplate( dialect, typeConfiguration ); @@ -249,24 +241,24 @@ public JoinedSubclassEntityPersister( isNullableTable = new boolean[tableSpan]; isInverseTable = new boolean[tableSpan]; - final List joinClosure = persistentClass.getJoinClosure(); + final var joinClosure = persistentClass.getJoinClosure(); for ( int i = 0; i < joinClosure.size(); i++ ) { - final Join join = joinClosure.get(i); + final var join = joinClosure.get(i); isNullableTable[i] = join.isOptional(); isInverseTable[i] = join.isInverse(); tableNames.add( determineTableName( join.getTable() ) ); - final KeyValue key = join.getKey(); + final var key = join.getKey(); final int joinIdColumnSpan = key.getColumnSpan(); final String[] keyCols = new String[joinIdColumnSpan]; final String[] keyColReaders = new String[joinIdColumnSpan]; final String[] keyColReaderTemplates = new String[joinIdColumnSpan]; - final List columns = key.getColumns(); + final var columns = key.getColumns(); for ( int k = 0; k < joinIdColumnSpan; k++ ) { - final Column column = columns.get(k); + final var column = columns.get(k); keyCols[k] = column.getQuotedName( dialect ); keyColReaders[k] = column.getReadExpr( dialect ); keyColReaderTemplates[k] = column.getTemplate( dialect, typeConfiguration ); @@ -282,20 +274,20 @@ public JoinedSubclassEntityPersister( naturalOrderTableKeyColumns = to2DStringArray( keyColumns ); final String[][] naturalOrderTableKeyColumnReaders = to2DStringArray( keyColumnReaders ); final String[][] naturalOrderTableKeyColumnReaderTemplates = to2DStringArray( keyColumnReaderTemplates ); - naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray( cascadeDeletes ); + naturalOrderCascadeDeleteEnabled = toBooleanArray( cascadeDeletes ); final ArrayList subclassTableNames = new ArrayList<>(); final ArrayList isConcretes = new ArrayList<>(); final ArrayList isNullables = new ArrayList<>(); final ArrayList allKeyColumns = new ArrayList<>(); - for ( Table table : persistentClass.getSubclassTableClosure() ) { + for ( var table : persistentClass.getSubclassTableClosure() ) { isConcretes.add( persistentClass.isClassOrSuperclassTable( table ) ); isNullables.add( false ); final String tableName = determineTableName( table ); subclassTableNames.add( tableName ); final String[] key = new String[idColumnSpan]; - final List columns = table.getPrimaryKey().getColumnsInOriginalOrder(); + final var columns = table.getPrimaryKey().getColumnsInOriginalOrder(); for ( int k = 0; k < idColumnSpan; k++ ) { key[k] = columns.get(k).getQuotedName( dialect ); } @@ -303,14 +295,14 @@ public JoinedSubclassEntityPersister( } //Add joins - for ( Join join : persistentClass.getSubclassJoinClosure() ) { - final Table joinTable = join.getTable(); + for ( var join : persistentClass.getSubclassJoinClosure() ) { + final var joinTable = join.getTable(); isConcretes.add( persistentClass.isClassOrSuperclassTable( joinTable ) ); isNullables.add( join.isOptional() ); final String joinTableName = determineTableName( joinTable ); subclassTableNames.add( joinTableName ); final String[] key = new String[idColumnSpan]; - final List columns = joinTable.getPrimaryKey().getColumnsInOriginalOrder(); + final var columns = joinTable.getPrimaryKey().getColumnsInOriginalOrder(); for ( int k = 0; k < idColumnSpan; k++ ) { key[k] = columns.get(k).getQuotedName( dialect ); } @@ -319,8 +311,8 @@ public JoinedSubclassEntityPersister( final String[] naturalOrderSubclassTableNameClosure = toStringArray( subclassTableNames ); final String[][] naturalOrderSubclassTableKeyColumnClosure = to2DStringArray( allKeyColumns ); - isClassOrSuperclassTable = ArrayHelper.toBooleanArray( isConcretes ); - isNullableSubclassTable = ArrayHelper.toBooleanArray( isNullables ); + isClassOrSuperclassTable = toBooleanArray( isConcretes ); + isNullableSubclassTable = toBooleanArray( isNullables ); constraintOrderedTableNames = new String[naturalOrderSubclassTableNameClosure.length]; constraintOrderedKeyColumnNames = new String[naturalOrderSubclassTableNameClosure.length][]; @@ -345,7 +337,7 @@ public JoinedSubclassEntityPersister( subclassTableNameClosure = reverseFirst( naturalOrderSubclassTableNameClosure, coreTableSpan ); subclassTableKeyColumnClosure = reverseFirst( naturalOrderSubclassTableKeyColumnClosure, coreTableSpan ); - spaces = ArrayHelper.join( this.tableNames, toStringArray( persistentClass.getSynchronizedTables() ) ); + spaces = join( this.tableNames, toStringArray( persistentClass.getSynchronizedTables() ) ); // Custom sql customSQLInsert = new String[tableSpan]; @@ -386,7 +378,7 @@ public JoinedSubclassEntityPersister( } int j = coreTableSpan; - for ( Join join : persistentClass.getJoinClosure() ) { + for ( var join : persistentClass.getJoinClosure() ) { isInverseTable[j] = join.isInverse(); isNullableTable[j] = join.isOptional(); @@ -405,14 +397,16 @@ public JoinedSubclassEntityPersister( j++; } + final var sqlStringGenerationContext = creationContext.getSqlStringGenerationContext(); + // PROPERTIES final int hydrateSpan = getPropertySpan(); naturalOrderPropertyTableNumbers = new int[hydrateSpan]; - final List propertyClosure = persistentClass.getPropertyClosure(); + final var propertyClosure = persistentClass.getPropertyClosure(); for ( int i = 0; i < propertyClosure.size(); i++ ) { final String tableName = propertyClosure.get(i).getValue().getTable() - .getQualifiedName( creationContext.getSqlStringGenerationContext() ); + .getQualifiedName( sqlStringGenerationContext ); naturalOrderPropertyTableNumbers[i] = getTableId( tableName, naturalOrderTableNames ); } @@ -424,17 +418,16 @@ public JoinedSubclassEntityPersister( final ArrayList propTableNumbers = new ArrayList<>(); final ArrayList columns = new ArrayList<>(); - for ( Property property : persistentClass.getSubclassPropertyClosure() ) { + for ( var property : persistentClass.getSubclassPropertyClosure() ) { final String tableName = property.getValue().getTable(). - getQualifiedName( creationContext.getSqlStringGenerationContext() ); + getQualifiedName( sqlStringGenerationContext ); final Integer tableNumber = getTableId( tableName, subclassTableNameClosure ); final Integer naturalTableNumber = getTableId( tableName, naturalOrderSubclassTableNameClosure ); propTableNumbers.add( tableNumber ); - for ( Selectable selectable : property.getSelectables() ) { - if ( !selectable.isFormula() ) { + for ( var selectable : property.getSelectables() ) { + if ( selectable instanceof Column column ) { columnTableNumbers.add( naturalTableNumber ); - Column column = (Column) selectable; columns.add( column.getQuotedName( dialect ) ); } } @@ -462,24 +455,30 @@ public JoinedSubclassEntityPersister( discriminatorValuesByTableName = linkedMapOfSize( subclassSpan + 1 ); discriminatorColumnNameByTableName = linkedMapOfSize( subclassSpan + 1 ); - final Table table = persistentClass.getTable(); + final var table = persistentClass.getTable(); discriminatorValues = new String[subclassSpan]; discriminatorAbstract = new boolean[subclassSpan]; - initDiscriminatorProperties( dialect, subclassSpanMinusOne, table, discriminatorValue, isAbstract( persistentClass) ); + initDiscriminatorProperties( + dialect, + subclassSpanMinusOne, + table, + discriminatorValue, + isAbstract( persistentClass) + ); notNullColumnTableNumbers = new int[subclassSpan]; final int id = getTableId( - table.getQualifiedName( creationContext.getSqlStringGenerationContext() ), + table.getQualifiedName( sqlStringGenerationContext ), subclassTableNameClosure ); notNullColumnTableNumbers[subclassSpanMinusOne] = id; notNullColumnNames = new String[subclassSpan]; notNullColumnNames[subclassSpanMinusOne] = subclassTableKeyColumnClosure[id][0]; - final List subclasses = persistentClass.getSubclasses(); + final var subclasses = persistentClass.getSubclasses(); for ( int k = 0; k < subclasses.size(); k++ ) { - final Subclass subclass = subclasses.get(k); - final Table subclassTable = subclass.getTable(); + final var subclass = subclasses.get(k); + final var subclassTable = subclass.getTable(); if ( persistentClass.isPolymorphic() ) { final Object discriminatorValue = explicitDiscriminatorColumnName != null ? DiscriminatorHelper.getDiscriminatorValue( subclass ) @@ -490,7 +489,7 @@ public JoinedSubclassEntityPersister( initDiscriminatorProperties( dialect, k, subclassTable, discriminatorValue, isAbstract( subclass ) ); subclassesByDiscriminatorValue.put( discriminatorValue, subclass.getEntityName() ); final int tableId = getTableId( - subclassTable.getQualifiedName( creationContext.getSqlStringGenerationContext() ), + subclassTable.getQualifiedName( sqlStringGenerationContext ), subclassTableNameClosure ); notNullColumnTableNumbers[k] = tableId; @@ -501,7 +500,7 @@ public JoinedSubclassEntityPersister( subclassNamesBySubclassTable = buildSubclassNamesBySubclassTableMapping( persistentClass, - creationContext.getSqlStringGenerationContext() + sqlStringGenerationContext ); initSubclassPropertyAliasesMap( persistentClass ); @@ -574,10 +573,11 @@ private String[][] buildSubclassNamesBySubclassTableMapping( if ( numberOfSubclassTables == 0 ) { return new String[0][]; } - - final String[][] mapping = new String[numberOfSubclassTables][]; - processPersistentClassHierarchy( persistentClass, true, mapping, context ); - return mapping; + else { + final String[][] mapping = new String[numberOfSubclassTables][]; + processPersistentClassHierarchy( persistentClass, true, mapping, context ); + return mapping; + } } private Set processPersistentClassHierarchy( @@ -585,30 +585,22 @@ private Set processPersistentClassHierarchy( boolean isBase, String[][] mapping, SqlStringGenerationContext context) { - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // collect all the class names that indicate that the "main table" of the given PersistentClass should be - // included when one of the collected class names is used in TREAT + // collect all the class names that indicate that the "main table" + // of the given PersistentClass should be included when one of the + // collected class names is used in TREAT final Set classNames = new HashSet<>(); - - for ( Subclass subclass : persistentClass.getDirectSubclasses() ) { - final Set subclassSubclassNames = - processPersistentClassHierarchy( subclass, false, mapping, context ); - classNames.addAll( subclassSubclassNames ); + for ( var subclass : persistentClass.getDirectSubclasses() ) { + classNames.addAll( processPersistentClassHierarchy( subclass, false, mapping, context ) ); } - classNames.add( persistentClass.getEntityName() ); - if ( !isBase ) { - MappedSuperclass msc = persistentClass.getSuperMappedSuperclass(); - while ( msc != null ) { - classNames.add( msc.getMappedClass().getName() ); - msc = msc.getSuperMappedSuperclass(); + var mappedSuperclass = persistentClass.getSuperMappedSuperclass(); + while ( mappedSuperclass != null ) { + classNames.add( mappedSuperclass.getMappedClass().getName() ); + mappedSuperclass = mappedSuperclass.getSuperMappedSuperclass(); } - associateSubclassNamesToSubclassTableIndexes( persistentClass, classNames, mapping, context ); } - return classNames; } @@ -617,11 +609,9 @@ private void associateSubclassNamesToSubclassTableIndexes( Set classNames, String[][] mapping, SqlStringGenerationContext context) { - final String tableName = persistentClass.getTable().getQualifiedName( context ); associateSubclassNamesToSubclassTableIndex( tableName, classNames, mapping ); - - for ( Join join : persistentClass.getJoins() ) { + for ( var join : persistentClass.getJoins() ) { final String secondaryTableName = join.getTable().getQualifiedName( context ); associateSubclassNamesToSubclassTableIndex( secondaryTableName, classNames, mapping ); } @@ -679,7 +669,7 @@ protected void visitMutabilityOrderedTables(MutabilityOrderedTableConsumer consu consumer.consume( tableName, tableIndex, - () -> (columnConsumer) -> columnConsumer.accept( + () -> columnConsumer -> columnConsumer.accept( tableName, getIdentifierMapping(), naturalOrderTableKeyColumns[tableIndex] @@ -748,25 +738,28 @@ public String getDiscriminatorAlias() { @Override public void addDiscriminatorToInsertGroup(MutationGroupBuilder insertGroupBuilder) { if ( explicitDiscriminatorColumnName != null ) { - final TableInsertBuilder tableInsertBuilder = insertGroupBuilder.getTableDetailsBuilder( getRootTableName() ); - final String discriminatorValueToUse; - if ( discriminatorValue == NULL_DISCRIMINATOR ) { - discriminatorValueToUse = "null"; - } - else if ( discriminatorValue == NOT_NULL_DISCRIMINATOR ) { - discriminatorValueToUse = "not null"; - } - else { - discriminatorValueToUse = discriminatorSQLString; - } + final TableInsertBuilder tableInsertBuilder = + insertGroupBuilder.getTableDetailsBuilder( getRootTableName() ); tableInsertBuilder.addValueColumn( explicitDiscriminatorColumnName, - discriminatorValueToUse, + getDiscriminatorValueString(), getDiscriminatorMapping().getJdbcMapping() ); } } + private String getDiscriminatorValueString() { + if ( discriminatorValue == NULL_DISCRIMINATOR ) { + return "null"; + } + else if ( discriminatorValue == NOT_NULL_DISCRIMINATOR ) { + return "not null"; + } + else { + return discriminatorSQLString; + } + } + @Override public String[] getPropertySpaces() { return spaces; // don't need subclass tables, because they can't appear in conditions @@ -874,31 +867,29 @@ protected boolean isSubclassTableIndicatedByTreatAsDeclarations( if ( treatAsDeclarations == null || treatAsDeclarations.isEmpty() ) { return false; } - - final String[] inclusionSubclassNameClosure = getSubclassNameClosureBySubclassTable( subclassTableNumber ); - - // NOTE : we assume the entire hierarchy is joined-subclass here - for ( String subclassName : treatAsDeclarations ) { - for ( String inclusionSubclassName : inclusionSubclassNameClosure ) { - if ( inclusionSubclassName.equals( subclassName ) ) { - return true; + else { + final String[] inclusionSubclassNameClosure = + getSubclassNameClosureBySubclassTable( subclassTableNumber ); + // NOTE: we assume the entire hierarchy is joined-subclass here + for ( String subclassName : treatAsDeclarations ) { + for ( String inclusionSubclassName : inclusionSubclassNameClosure ) { + if ( inclusionSubclassName.equals( subclassName ) ) { + return true; + } } } + return false; } - - return false; } private String[] getSubclassNameClosureBySubclassTable(int subclassTableNumber) { final int index = subclassTableNumber - getTableSpan(); - if ( index >= subclassNamesBySubclassTable.length ) { throw new IllegalArgumentException( "Given subclass table number is outside expected range [" + (subclassNamesBySubclassTable.length -1) + "] as defined by subclassTableNameClosure/subclassClosure" ); } - return subclassNamesBySubclassTable[index]; } @@ -917,13 +908,14 @@ protected int determineTableNumberForColumn(String columnName) { // HHH-7630: In case the naturalOrder/identifier column is explicitly given in the ordering, check here. for ( int i = 0, max = naturalOrderTableKeyColumns.length; i < max; i++ ) { final String[] keyColumns = naturalOrderTableKeyColumns[i]; - if ( ArrayHelper.contains( keyColumns, columnName ) ) { + if ( contains( keyColumns, columnName ) ) { return naturalOrderPropertyTableNumbers[i]; } } - for (int i = 0, max = subclassColumnClosure.length; i < max; i++ ) { - final boolean quoted = subclassColumnClosure[i].startsWith( "\"" ) + for ( int i = 0, max = subclassColumnClosure.length; i < max; i++ ) { + final boolean quoted = + subclassColumnClosure[i].startsWith( "\"" ) && subclassColumnClosure[i].endsWith( "\"" ); if ( quoted ) { if ( subclassColumnClosure[i].equals( columnName ) ) { @@ -943,10 +935,10 @@ protected int determineTableNumberForColumn(String columnName) { @Override public Object forceVersionIncrement(Object id, Object currentVersion, SharedSessionContractImplementor session) { - if ( getSuperMappingType() != null ) { - return getSuperMappingType().getEntityPersister().forceVersionIncrement( id, currentVersion, session ); - } - return super.forceVersionIncrement( id, currentVersion, session ); + final var superMappingType = getSuperMappingType(); + return superMappingType != null + ? superMappingType.getEntityPersister().forceVersionIncrement( id, currentVersion, session ) + : super.forceVersionIncrement( id, currentVersion, session ); } @Override @@ -955,10 +947,10 @@ public Object forceVersionIncrement( Object currentVersion, boolean batching, SharedSessionContractImplementor session) throws HibernateException { - if ( getSuperMappingType() != null ) { - return getSuperMappingType().getEntityPersister().forceVersionIncrement( id, currentVersion, session ); - } - return super.forceVersionIncrement( id, currentVersion, batching, session ); + final var superMappingType = getSuperMappingType(); + return superMappingType != null + ? superMappingType.getEntityPersister().forceVersionIncrement( id, currentVersion, session ) + : super.forceVersionIncrement( id, currentVersion, batching, session ); } @Override @@ -971,8 +963,7 @@ protected EntityVersionMapping generateVersionMapping( } else { if ( getTableName().equals( getVersionedTableName() ) ) { - final int versionPropertyIndex = getVersionProperty(); - final String versionPropertyName = getPropertyNames()[versionPropertyIndex]; + final String versionPropertyName = getPropertyNames()[this.getVersionPropertyIndex()]; return creationProcess.processSubPart( versionPropertyName, (role, process) -> generateVersionMapping( @@ -993,40 +984,32 @@ else if ( getSuperMappingType() != null ) { @Override protected EntityIdentifierMapping generateIdentifierMapping( Supplier templateInstanceCreator, - PersistentClass bootEntityDescriptor, + PersistentClass persistentClass, MappingModelCreationProcess creationProcess) { final Type idType = getIdentifierType(); - - if ( idType instanceof CompositeType cidType ) { - - // NOTE: the term `isEmbedded` here uses Hibernate's older (pre-JPA) naming for its "non-aggregated" - // composite-id support. It unfortunately conflicts with the JPA usage of "embedded". Here we normalize - // the legacy naming to the more descriptive encapsulated versus non-encapsulated phrasing - - final boolean encapsulated = ! cidType.isEmbedded(); - if ( encapsulated ) { - // we have an `@EmbeddedId` - return buildEncapsulatedCompositeIdentifierMapping( - this, - bootEntityDescriptor.getIdentifierProperty(), - bootEntityDescriptor.getIdentifierProperty().getName(), - getTableName(), - tableKeyColumns[0], - cidType, - creationProcess - ); - } - - // otherwise we have a non-encapsulated composite-identifier - return generateNonEncapsulatedCompositeIdentifierMapping( creationProcess, bootEntityDescriptor ); + if ( idType instanceof CompositeType compositeIdType ) { + return compositeIdentifierMapping( persistentClass, creationProcess, compositeIdType ); + } + else if ( idType instanceof BasicType basicIdType ) { + return basicIdentifierMapping( templateInstanceCreator, persistentClass, creationProcess, basicIdType ); } + else { + throw new AssertionFailure( "Unrecognized id type" ); + } + } + private BasicEntityIdentifierMappingImpl basicIdentifierMapping( + Supplier templateInstanceCreator, + PersistentClass persistentClass, + MappingModelCreationProcess creationProcess, + BasicType idType) { + final var identifier = persistentClass.getIdentifier(); final String columnDefinition; final Long length; final Integer arrayLength; final Integer precision; final Integer scale; - if ( bootEntityDescriptor.getIdentifier() == null ) { + if ( identifier == null ) { columnDefinition = null; length = null; arrayLength = null; @@ -1034,18 +1017,19 @@ protected EntityIdentifierMapping generateIdentifierMapping( scale = null; } else { - final Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 ); + final var column = identifier.getColumns().get( 0 ); columnDefinition = column.getSqlType(); length = column.getLength(); arrayLength = column.getArrayLength(); precision = column.getPrecision(); scale = column.getScale(); } - final Value value = bootEntityDescriptor.getIdentifierProperty().getValue(); + final var identifierProperty = persistentClass.getIdentifierProperty(); + final var value = identifierProperty.getValue(); return new BasicEntityIdentifierMappingImpl( this, templateInstanceCreator, - bootEntityDescriptor.getIdentifierProperty().getName(), + identifierProperty.getName(), getTableName(), tableKeyColumns[0][0], columnDefinition, @@ -1055,11 +1039,39 @@ protected EntityIdentifierMapping generateIdentifierMapping( scale, value.isColumnInsertable( 0 ), value.isColumnUpdateable( 0 ), - (BasicType) idType, + idType, creationProcess ); } + private EntityIdentifierMapping compositeIdentifierMapping( + PersistentClass persistentClass, + MappingModelCreationProcess creationProcess, + CompositeType compositeIdType) { + // NOTE: the term `isEmbedded` here uses Hibernate's older (pre-JPA) naming for its + // "non-aggregated" composite-id support. It unfortunately conflicts with the + // JPA usage of "embedded". Here we normalize the legacy naming to the more + // descriptive encapsulated versus non-encapsulated phrasing + final boolean encapsulated = !compositeIdType.isEmbedded(); + if ( encapsulated ) { + // we have an `@EmbeddedId` + final var identifierProperty = persistentClass.getIdentifierProperty(); + return buildEncapsulatedCompositeIdentifierMapping( + this, + identifierProperty, + identifierProperty.getName(), + getTableName(), + tableKeyColumns[0], + compositeIdType, + creationProcess + ); + } + else { + // otherwise we have a non-encapsulated composite-identifier + return generateNonEncapsulatedCompositeIdentifierMapping( creationProcess, persistentClass ); + } + } + @Override protected boolean isPhysicalDiscriminator() { return explicitDiscriminatorColumnName != null; @@ -1067,7 +1079,7 @@ protected boolean isPhysicalDiscriminator() { @Override protected EntityDiscriminatorMapping generateDiscriminatorMapping(PersistentClass bootEntityDescriptor) { - final EntityMappingType superMappingType = getSuperMappingType(); + final var superMappingType = getSuperMappingType(); if ( superMappingType != null ) { return superMappingType.getDiscriminatorMapping(); } @@ -1102,7 +1114,6 @@ protected EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMapp MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { assert declaredAttributeMappings != null; - return buildNonEncapsulatedCompositeIdentifierMapping( this, getTableName(), @@ -1134,7 +1145,7 @@ public TableDetails getIdentifierTableDetails() { @Override public void pruneForSubclasses(TableGroup tableGroup, Map entityNameUses) { final Set retainedTableReferences = new HashSet<>( entityNameUses.size() ); - final MappingMetamodelImplementor metamodel = getFactory().getMappingMetamodel(); + final var metamodel = getFactory().getMappingMetamodel(); // We can only do this optimization if the table group reports canUseInnerJoins or isRealTableGroup, // because the switch for table reference joins to INNER must be cardinality preserving. // If canUseInnerJoins is true, this is trivially given, but also if the table group is real @@ -1142,61 +1153,21 @@ public void pruneForSubclasses(TableGroup tableGroup, Map final boolean innerJoinOptimization = tableGroup.canUseInnerJoins() || tableGroup.isRealTableGroup(); final Set tablesToInnerJoin = innerJoinOptimization ? new HashSet<>() : null; boolean needsTreatDiscriminator = false; - for ( Map.Entry entry : entityNameUses.entrySet() ) { - final EntityNameUse.UseKind useKind = entry.getValue().getKind(); - final JoinedSubclassEntityPersister persister = - (JoinedSubclassEntityPersister) metamodel.findEntityDescriptor( entry.getKey() ); + for ( var entry : entityNameUses.entrySet() ) { + final var useKind = entry.getValue().getKind(); + final var persister = (JoinedSubclassEntityPersister) metamodel.findEntityDescriptor( entry.getKey() ); // The following block tries to figure out what can be inner joined and which super class table joins can be omitted - if ( innerJoinOptimization && ( useKind == EntityNameUse.UseKind.TREAT || useKind == EntityNameUse.UseKind.FILTER ) ) { - final String[] subclassTableNames = persister.getSubclassTableNames(); - // Build the intersection of all tables names that are of the class or super class - // These are the tables that can be safely inner joined - final Set classOrSuperclassTables = new HashSet<>( subclassTableNames.length ); - for ( int i = 0; i < subclassTableNames.length; i++ ) { - if ( persister.isClassOrSuperclassTable[i] ) { - classOrSuperclassTables.add( subclassTableNames[i] ); - } - } - if ( tablesToInnerJoin.isEmpty() ) { - tablesToInnerJoin.addAll( classOrSuperclassTables ); - } - else { - tablesToInnerJoin.retainAll( classOrSuperclassTables ); - } - if ( useKind == EntityNameUse.UseKind.FILTER && explicitDiscriminatorColumnName == null ) { - // If there is no discriminator column, - // we must retain all joins to subclass tables to be able to discriminate the rows - for ( int i = 0; i < subclassTableNames.length; i++ ) { - if ( !persister.isClassOrSuperclassTable[i] ) { - final String subclassTableName = subclassTableNames[i]; - final TableReference mainTableReference = tableGroup.getTableReference( - null, - subclassTableName, - false - ); - if ( mainTableReference == null ) { - throw new UnknownTableReferenceException( - subclassTableName, - "Couldn't find table reference" - ); - } - retainedTableReferences.add( mainTableReference ); - } - } - } + if ( innerJoinOptimization ) { + optimizeInnerJoins( tableGroup, useKind, persister, tablesToInnerJoin, retainedTableReferences ); } final String tableName = persister.getTableName(); - final TableReference mainTableReference = tableGroup.getTableReference( - null, - tableName, - false - ); + final var mainTableReference = tableGroup.getTableReference( null, tableName, false ); if ( mainTableReference != null ) { retainedTableReferences.add( mainTableReference ); } final String sqlWhereStringTableExpression = persister.getSqlWhereStringTableExpression(); if ( sqlWhereStringTableExpression != null ) { - final TableReference tableReference = tableGroup.getTableReference( sqlWhereStringTableExpression ); + final var tableReference = tableGroup.getTableReference( sqlWhereStringTableExpression ); if ( tableReference != null ) { retainedTableReferences.add( tableReference ); } @@ -1219,13 +1190,14 @@ public void pruneForSubclasses(TableGroup tableGroup, Map } } - final List tableReferenceJoins = tableGroup.getTableReferenceJoins(); + final var tableReferenceJoins = tableGroup.getTableReferenceJoins(); if ( needsTreatDiscriminator ) { if ( tableReferenceJoins.isEmpty() ) { // We need to apply the discriminator predicate to the primary table reference itself - final String discriminatorPredicate = getPrunedDiscriminatorPredicate( entityNameUses, metamodel, "t" ); + final String discriminatorPredicate = + getPrunedDiscriminatorPredicate( entityNameUses, metamodel, "t" ); if ( discriminatorPredicate != null ) { - final NamedTableReference tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); + final var tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); tableReference.setPrunedTableExpression( "(select * from " + getRootTableName() + " t where " + discriminatorPredicate + ")" ); } } @@ -1239,7 +1211,7 @@ public void pruneForSubclasses(TableGroup tableGroup, Map ); int i = 0; for ( ; !applied && i < tableReferenceJoins.size(); i++ ) { - final TableReferenceJoin join = tableReferenceJoins.get( i ); + final var join = tableReferenceJoins.get( i ); applied = applyDiscriminatorPredicate( join, join.getJoinedTableReference(), entityNameUses, metamodel ); } assert applied : "Could not apply treat discriminator predicate to root table join"; @@ -1249,37 +1221,80 @@ public void pruneForSubclasses(TableGroup tableGroup, Map } } } - if ( tableReferenceJoins.isEmpty() ) { - return; + if ( !tableReferenceJoins.isEmpty() ) { + // The optimization is to remove all table reference joins that are not contained in the retainedTableReferences + // In addition, we switch from a possible LEFT join, to an INNER join for all tablesToInnerJoin + if ( innerJoinOptimization ) { + final var oldJoins = tableReferenceJoins.toArray( new TableReferenceJoin[0] ); + tableReferenceJoins.clear(); + for ( var oldJoin : oldJoins ) { + final var joinedTableReference = oldJoin.getJoinedTableReference(); + if ( retainedTableReferences.contains( joinedTableReference ) ) { + final var join = + oldJoin.getJoinType() != SqlAstJoinType.INNER + && tablesToInnerJoin.contains( joinedTableReference.getTableExpression() ) + ? new TableReferenceJoin( true, joinedTableReference, oldJoin.getPredicate() ) + : oldJoin; + tableReferenceJoins.add( join ); + } + else { + for ( int i = subclassCoreTableSpan; i < subclassTableNameClosure.length; i++ ) { + if ( joinedTableReference.getTableExpression().equals( subclassTableNameClosure[i] ) ) { + // Retain joins to secondary tables + tableReferenceJoins.add( oldJoin ); + break; + } + } + } + } + } + else { + tableReferenceJoins.removeIf( join -> !retainedTableReferences.contains( join.getJoinedTableReference() ) ); + } } - // The optimization is to remove all table reference joins that are not contained in the retainedTableReferences - // In addition, we switch from a possible LEFT join, to an INNER join for all tablesToInnerJoin - if ( innerJoinOptimization ) { - final TableReferenceJoin[] oldJoins = tableReferenceJoins.toArray( new TableReferenceJoin[0] ); - tableReferenceJoins.clear(); - for ( TableReferenceJoin oldJoin : oldJoins ) { - final NamedTableReference joinedTableReference = oldJoin.getJoinedTableReference(); - if ( retainedTableReferences.contains( joinedTableReference ) ) { - final TableReferenceJoin join = oldJoin.getJoinType() != SqlAstJoinType.INNER - && tablesToInnerJoin.contains( joinedTableReference.getTableExpression() ) - ? new TableReferenceJoin( true, joinedTableReference, oldJoin.getPredicate() ) - : oldJoin; - tableReferenceJoins.add( join ); + } + + private void optimizeInnerJoins( + TableGroup tableGroup, + EntityNameUse.UseKind useKind, + JoinedSubclassEntityPersister persister, + Set tablesToInnerJoin, + Set retainedTableReferences) { + if ( useKind == EntityNameUse.UseKind.TREAT || useKind == EntityNameUse.UseKind.FILTER ) { + final String[] subclassTableNames = persister.getSubclassTableNames(); + // Build the intersection of all tables names that are of the class or super class + // These are the tables that can be safely inner joined + final Set classOrSuperclassTables = new HashSet<>( subclassTableNames.length ); + for ( int i = 0; i < subclassTableNames.length; i++ ) { + if ( persister.isClassOrSuperclassTable[i] ) { + classOrSuperclassTables.add( subclassTableNames[i] ); } - else { - for ( int i = subclassCoreTableSpan; i < subclassTableNameClosure.length; i++ ) { - if ( joinedTableReference.getTableExpression().equals( subclassTableNameClosure[i] ) ) { - // Retain joins to secondary tables - tableReferenceJoins.add( oldJoin ); - break; + } + if ( tablesToInnerJoin.isEmpty() ) { + tablesToInnerJoin.addAll( classOrSuperclassTables ); + } + else { + tablesToInnerJoin.retainAll( classOrSuperclassTables ); + } + if ( useKind == EntityNameUse.UseKind.FILTER && explicitDiscriminatorColumnName == null ) { + // If there is no discriminator column, + // we must retain all joins to subclass tables to be able to discriminate the rows + for ( int i = 0; i < subclassTableNames.length; i++ ) { + if ( !persister.isClassOrSuperclassTable[i] ) { + final String subclassTableName = subclassTableNames[i]; + final var mainTableReference = + tableGroup.getTableReference( null, subclassTableName, false ); + if ( mainTableReference == null ) { + throw new UnknownTableReferenceException( + subclassTableName, + "Couldn't find table reference" + ); } + retainedTableReferences.add( mainTableReference ); } } } } - else { - tableReferenceJoins.removeIf( join -> !retainedTableReferences.contains( join.getJoinedTableReference() ) ); - } } @Override @@ -1297,11 +1312,8 @@ private boolean applyDiscriminatorPredicate( Map entityNameUses, MappingMetamodelImplementor metamodel) { if ( tableReference.getTableExpression().equals( getRootTableName() ) ) { - final String discriminatorPredicate = getPrunedDiscriminatorPredicate( - entityNameUses, - metamodel, - "t" - ); + final String discriminatorPredicate = + getPrunedDiscriminatorPredicate( entityNameUses, metamodel, "t" ); // null means we're filtering for all subtypes, so we don't need to apply a predicate if ( discriminatorPredicate != null ) { assert join.getJoinType() == SqlAstJoinType.INNER : "Found table reference join with root table of non-INNER type: " + join.getJoinType(); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index 28cf8e4fcd48..ca5097a6abca 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -6,39 +6,32 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; +import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.Internal; import org.hibernate.MappingException; import org.hibernate.Remove; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess; -import org.hibernate.dialect.Dialect; import org.hibernate.internal.DynamicFilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jdbc.Expectation; import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; -import org.hibernate.mapping.Join; import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.Selectable; -import org.hibernate.mapping.Subclass; -import org.hibernate.mapping.Table; -import org.hibernate.mapping.Value; +import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.mapping.TableDetails; -import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.model.ast.builder.MutationGroupBuilder; import org.hibernate.sql.model.ast.builder.TableInsertBuilder; import org.hibernate.type.BasicType; -import org.hibernate.type.spi.TypeConfiguration; +import static org.hibernate.internal.util.collections.ArrayHelper.indexOf; +import static org.hibernate.internal.util.collections.ArrayHelper.join; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray; import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray; @@ -115,8 +108,8 @@ public SingleTableEntityPersister( final RuntimeModelCreationContext creationContext) throws HibernateException { super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext ); - final Dialect dialect = creationContext.getDialect(); - final TypeConfiguration typeConfiguration = creationContext.getTypeConfiguration(); + final var dialect = creationContext.getDialect(); + final var typeConfiguration = creationContext.getTypeConfiguration(); // CLASS + TABLE @@ -124,9 +117,7 @@ public SingleTableEntityPersister( // todo (6.2) : see note on AbstractEntityPersister#getTableName(int) qualifiedTableNames = new String[joinSpan]; - final Table table = persistentClass.getRootTable(); - final String rootTableName = determineTableName( table ); - qualifiedTableNames[0] = rootTableName; + qualifiedTableNames[0] = determineTableName( persistentClass.getRootTable() ); isInverseTable = new boolean[joinSpan]; isNullableTable = new boolean[joinSpan]; @@ -163,13 +154,13 @@ public SingleTableEntityPersister( // JOINS - final List joinClosure = persistentClass.getJoinClosure(); + final var joinClosure = persistentClass.getJoinClosure(); boolean hasDuplicateTableName = false; for ( int j = 1; j - 1 < joinClosure.size(); j++ ) { - Join join = joinClosure.get( j - 1 ); + final var join = joinClosure.get( j - 1 ); qualifiedTableNames[j] = determineTableName( join.getTable() ); hasDuplicateTableName = hasDuplicateTableName - || ArrayHelper.indexOf( qualifiedTableNames, j, qualifiedTableNames[j] ) != -1; + || indexOf( qualifiedTableNames, j, qualifiedTableNames[j] ) != -1; isInverseTable[j] = join.isInverse(); isNullableTable[j] = join.isOptional(); cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() && dialect.supportsCascadeDelete(); @@ -188,7 +179,7 @@ public SingleTableEntityPersister( keyColumnNames[j] = new String[join.getKey().getColumnSpan()]; - final List columns = join.getKey().getColumns(); + final var columns = join.getKey().getColumns(); for ( int i = 0; i < columns.size(); i++ ) { keyColumnNames[j][i] = columns.get( i ).getQuotedName( dialect ); } @@ -202,7 +193,7 @@ public SingleTableEntityPersister( constraintOrderedKeyColumnNames[position] = keyColumnNames[i]; } - spaces = ArrayHelper.join( qualifiedTableNames, toStringArray( persistentClass.getSynchronizedTables() ) ); + spaces = join( qualifiedTableNames, toStringArray( persistentClass.getSynchronizedTables() ) ); final ArrayList subclassTables = new ArrayList<>(); final ArrayList joinKeyColumns = new ArrayList<>(); @@ -214,16 +205,15 @@ public SingleTableEntityPersister( isConcretes.add( true ); isClassOrSuperclassJoins.add( true ); isNullables.add( false ); - for ( Join join : persistentClass.getSubclassJoinClosure() ) { + for ( var join : persistentClass.getSubclassJoinClosure() ) { isConcretes.add( persistentClass.isClassOrSuperclassTable( join.getTable() ) ); isClassOrSuperclassJoins.add( persistentClass.isClassOrSuperclassJoin( join ) ); isNullables.add( join.isOptional() ); - final String joinTableName = determineTableName( join.getTable() ); - subclassTables.add( joinTableName ); + subclassTables.add( determineTableName( join.getTable() ) ); final String[] keyCols = new String[join.getKey().getColumnSpan()]; - final List columns = join.getKey().getColumns(); + final var columns = join.getKey().getColumns(); for ( int i = 0; i < columns.size(); i++ ) { keyCols[i] = columns.get( i ).getQuotedName( dialect ); } @@ -239,32 +229,33 @@ public SingleTableEntityPersister( // DISCRIMINATOR if ( persistentClass.isPolymorphic() ) { - final Value discriminator = persistentClass.getDiscriminator(); + final var discriminator = persistentClass.getDiscriminator(); if ( discriminator == null ) { throw new MappingException( "discriminator mapping required for single table polymorphic persistence" ); } forceDiscriminator = persistentClass.isForceDiscriminator(); - final Selectable selectable = discriminator.getSelectables().get( 0 ); + final var selectable = discriminator.getSelectables().get( 0 ); discriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass ); discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass ); discriminatorSQLValue = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect ); discriminatorInsertable = isDiscriminatorInsertable( persistentClass ); - if ( discriminator.hasFormula() ) { - final Formula formula = (Formula) selectable; + if ( selectable instanceof Formula formula ) { discriminatorFormulaTemplate = formula.getTemplate( dialect, typeConfiguration ); discriminatorColumnName = null; discriminatorColumnReaders = null; discriminatorColumnReaderTemplate = null; discriminatorAlias = "clazz_"; } - else { - final Column column = (Column) selectable; + else if ( selectable instanceof Column column ) { discriminatorColumnName = column.getQuotedName( dialect ); discriminatorColumnReaders = column.getReadExpr( dialect ); discriminatorColumnReaderTemplate = column.getTemplate( dialect, typeConfiguration ); discriminatorAlias = column.getAlias( dialect, persistentClass.getRootTable() ); discriminatorFormulaTemplate = null; } + else { + throw new AssertionFailure( "Unrecognized selectable" ); + } } else { forceDiscriminator = false; @@ -282,7 +273,7 @@ public SingleTableEntityPersister( // PROPERTIES propertyTableNumbers = new int[getPropertySpan()]; - final List propertyClosure = persistentClass.getPropertyClosure(); + final var propertyClosure = persistentClass.getPropertyClosure(); for ( int k = 0; k < propertyClosure.size(); k++ ) { propertyTableNumbers[k] = persistentClass.getJoinNumber( propertyClosure.get( k ) ); } @@ -292,7 +283,7 @@ public SingleTableEntityPersister( final ArrayList propertyJoinNumbers = new ArrayList<>(); final Map subclassesByDiscriminatorValueLocal = new HashMap<>(); - for ( Property property : persistentClass.getSubclassPropertyClosure() ) { + for ( var property : persistentClass.getSubclassPropertyClosure() ) { propertyJoinNumbers.add( persistentClass.getJoinNumber( property ) ); } @@ -309,14 +300,13 @@ public SingleTableEntityPersister( ); // SUBCLASSES - final List subclasses = persistentClass.getSubclasses(); + final var subclasses = persistentClass.getSubclasses(); for ( int k = 0; k < subclasses.size(); k++ ) { - Subclass subclass = subclasses.get( k ); + final var subclass = subclasses.get( k ); subclassClosure[k] = subclass.getEntityName(); - Object subclassDiscriminatorValue = DiscriminatorHelper.getDiscriminatorValue( subclass ); addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, - subclassDiscriminatorValue, + DiscriminatorHelper.getDiscriminatorValue( subclass ), subclass.getEntityName() ); } @@ -478,7 +468,8 @@ public int getTableSpan() { @Override public void addDiscriminatorToInsertGroup(MutationGroupBuilder insertGroupBuilder) { if ( discriminatorInsertable ) { - final TableInsertBuilder tableInsertBuilder = insertGroupBuilder.getTableDetailsBuilder( getRootTableName() ); + final TableInsertBuilder tableInsertBuilder = + insertGroupBuilder.getTableDetailsBuilder( getRootTableName() ); tableInsertBuilder.addValueColumn( discriminatorColumnName, discriminatorValue == NULL_DISCRIMINATOR ? NULL : discriminatorSQLValue, @@ -559,40 +550,39 @@ public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { @Override public void pruneForSubclasses(TableGroup tableGroup, Map entityNameUses) { - if ( !needsDiscriminator() && entityNameUses.isEmpty() ) { - return; - } - // The following optimization is to add the discriminator filter fragment for all treated entity names - final MappingMetamodelImplementor mappingMetamodel = getFactory().getMappingMetamodel(); - - boolean containsTreatUse = false; - for ( Map.Entry entry : entityNameUses.entrySet() ) { - final EntityNameUse.UseKind useKind = entry.getValue().getKind(); - if ( useKind == EntityNameUse.UseKind.PROJECTION || useKind == EntityNameUse.UseKind.EXPRESSION ) { - // We only care about treat and filter uses which allow to reduce the amount of rows to select - continue; + if ( needsDiscriminator() || !entityNameUses.isEmpty() ) {// The following optimization is to add the discriminator filter fragment for all treated entity names + final var mappingMetamodel = getFactory().getMappingMetamodel(); + if ( containsTreatUse( entityNameUses, mappingMetamodel ) ) { + final String discriminatorPredicate = + getPrunedDiscriminatorPredicate( entityNameUses, mappingMetamodel, "t" ); + if ( discriminatorPredicate != null ) { + final var tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); + tableReference.setPrunedTableExpression( + "(select * from " + getTableName() + " t where " + discriminatorPredicate + ")" ); + } } - final EntityPersister persister = mappingMetamodel.getEntityDescriptor( entry.getKey() ); - // Filtering for abstract entities makes no sense, so ignore that - // Also, it makes no sense to filter for any of the super types, - // as the query will contain a filter for that already anyway - if ( useKind == EntityNameUse.UseKind.TREAT && !persister.isAbstract() - && ( getSuperMappingType() == null || !getSuperMappingType().isTypeOrSuperType( persister ) ) ) { - containsTreatUse = true; - break; - } - } - if ( !containsTreatUse ) { - // If we only have FILTER uses, we don't have to do anything here, - // because the BaseSqmToSqlAstConverter will already apply the type filter in the WHERE clause - return; + // Otherwise, if we only have FILTER uses, we don't have to do anything here because + // the BaseSqmToSqlAstConverter will already apply the type filter in the WHERE clause } + } - final String discriminatorPredicate = getPrunedDiscriminatorPredicate( entityNameUses, mappingMetamodel, "t" ); - if ( discriminatorPredicate != null ) { - final NamedTableReference tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); - tableReference.setPrunedTableExpression( "(select * from " + getTableName() + " t where " + discriminatorPredicate + ")" ); + private boolean containsTreatUse(Map entityNameUses, MappingMetamodel metamodel) { + for ( var entry : entityNameUses.entrySet() ) { + // We only care about treat uses which allow to reduce the amount of rows to select + if ( entry.getValue().getKind() == EntityNameUse.UseKind.TREAT ) { + final var persister = metamodel.getEntityDescriptor( entry.getKey() ); + // Filtering for abstract entities makes no sense, so ignore that + if ( !persister.isAbstract() ) { + // Also, it makes no sense to filter for any of the super types, + // as the query will contain a filter for that already anyway + final var superMappingType = getSuperMappingType(); + if ( superMappingType == null || !getSuperMappingType().isTypeOrSuperType( persister ) ) { + return true; + } + } + } } + return false; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java index e357f9202903..d91ff9018c3d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java @@ -7,11 +7,8 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -24,7 +21,6 @@ import org.hibernate.HibernateException; import org.hibernate.Internal; import org.hibernate.MappingException; -import org.hibernate.boot.Metadata; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess; import org.hibernate.dialect.Dialect; @@ -35,16 +31,12 @@ import org.hibernate.jdbc.Expectation; import org.hibernate.mapping.Column; import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Subclass; -import org.hibernate.mapping.Table; -import org.hibernate.metamodel.mapping.AttributeMappingsList; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.TableDetails; import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl; -import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.ast.spi.SqlAliasBase; @@ -58,6 +50,8 @@ import org.hibernate.type.BasicType; import org.hibernate.type.StandardBasicTypes; +import static java.util.Collections.addAll; +import static java.util.Collections.unmodifiableList; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray; import static org.hibernate.jdbc.Expectations.createExpectation; @@ -100,7 +94,7 @@ public UnionSubclassEntityPersister( validateGenerator(); - final Dialect dialect = creationContext.getDialect(); + final var dialect = creationContext.getDialect(); // TABLE @@ -132,7 +126,7 @@ public UnionSubclassEntityPersister( // SUBCLASSES subclassByDiscriminatorValue.put( persistentClass.getSubclassId(), persistentClass.getEntityName() ); if ( persistentClass.isPolymorphic() ) { - for ( Subclass subclass : persistentClass.getSubclasses() ) { + for ( var subclass : persistentClass.getSubclasses() ) { subclassByDiscriminatorValue.put( subclass.getSubclassId(), subclass.getEntityName() ); } } @@ -141,32 +135,32 @@ public UnionSubclassEntityPersister( //TODO: I'm not sure, but perhaps we should exclude // abstract denormalized tables? - int spacesSize = 1 + persistentClass.getSynchronizedTables().size(); + final int spacesSize = 1 + persistentClass.getSynchronizedTables().size(); spaces = new String[spacesSize]; spaces[0] = tableName; - Iterator iter = persistentClass.getSynchronizedTables().iterator(); + final var iter = persistentClass.getSynchronizedTables().iterator(); for ( int i = 1; i < spacesSize; i++ ) { spaces[i] = iter.next(); } - HashSet subclassTables = new HashSet<>(); - for ( Table table : persistentClass.getSubclassTableClosure() ) { + final HashSet subclassTables = new HashSet<>(); + for ( var table : persistentClass.getSubclassTableClosure() ) { subclassTables.add( determineTableName( table ) ); } subclassSpaces = toStringArray( subclassTables ); - subquery = generateSubquery( persistentClass, creationContext.getMetadata() ); + subquery = generateSubquery( persistentClass ); final List tableExpressions = new ArrayList<>( subclassSpaces.length * 2 ); - Collections.addAll( tableExpressions, subclassSpaces ); + addAll( tableExpressions, subclassSpaces ); tableExpressions.add( subquery ); - PersistentClass parentPersistentClass = persistentClass.getSuperclass(); + var parentPersistentClass = persistentClass.getSuperclass(); while ( parentPersistentClass != null ) { - tableExpressions.add( generateSubquery( parentPersistentClass, creationContext.getMetadata() ) ); + tableExpressions.add( generateSubquery( parentPersistentClass ) ); parentPersistentClass = parentPersistentClass.getSuperclass(); } - for ( PersistentClass subPersistentClass : persistentClass.getSubclassClosure() ) { - if ( subPersistentClass.hasSubclasses() ) { - tableExpressions.add( generateSubquery( subPersistentClass, creationContext.getMetadata() ) ); + for ( var subclassPersistentClass : persistentClass.getSubclassClosure() ) { + if ( subclassPersistentClass.hasSubclasses() ) { + tableExpressions.add( generateSubquery( subclassPersistentClass ) ); } } subclassTableExpressions = toStringArray( tableExpressions ); @@ -175,7 +169,7 @@ public UnionSubclassEntityPersister( final int idColumnSpan = getIdentifierColumnSpan(); final ArrayList tableNames = new ArrayList<>(); final ArrayList keyColumns = new ArrayList<>(); - for ( Table table : persistentClass.getSubclassTableClosure() ) { + for ( var table : persistentClass.getSubclassTableClosure() ) { if ( !table.isAbstractUnionTable() ) { tableNames.add( determineTableName( table ) ); final String[] key = new String[idColumnSpan]; @@ -221,13 +215,16 @@ public boolean containsTableReference(String tableExpression) { public UnionTableReference createPrimaryTableReference( SqlAliasBase sqlAliasBase, SqlAstCreationState creationState) { - sqlAliasBase = SqlAliasBase.from( - sqlAliasBase, - null, - this, - creationState.getSqlAliasBaseGenerator() + return new UnionTableReference( + getTableName(), + subclassTableExpressions, + SqlAliasBase.from( + sqlAliasBase, + null, + this, + creationState.getSqlAliasBaseGenerator() + ).generateNewAlias() ); - return new UnionTableReference( getTableName(), subclassTableExpressions, sqlAliasBase.generateNewAlias() ); } @Override @@ -358,7 +355,7 @@ public boolean hasMultipleTables() { @Override public void pruneForSubclasses(TableGroup tableGroup, Map entityNameUses) { - final NamedTableReference tableReference = (NamedTableReference) tableGroup.getTableReference( getRootTableName() ); + final var tableReference = (NamedTableReference) tableGroup.getTableReference( getRootTableName() ); if ( tableReference == null ) { throw new UnknownTableReferenceException( getRootTableName(), "Couldn't find table reference" ); } @@ -411,67 +408,62 @@ protected int[] getPropertyTableNumbers() { return new int[getPropertySpan()]; } - protected String generateSubquery(PersistentClass model, Metadata mapping) { - - final Dialect dialect = getFactory().getJdbcServices().getDialect(); - + protected String generateSubquery(PersistentClass model) { + final var factory = getFactory(); + final var sqlStringGenerationContext = factory.getSqlStringGenerationContext(); if ( !model.hasSubclasses() ) { - return model.getTable().getQualifiedName( getFactory().getSqlStringGenerationContext() ); + return model.getTable().getQualifiedName( sqlStringGenerationContext ); } - - final Set columns = new LinkedHashSet<>(); - for ( Table table : model.getSubclassTableClosure() ) { - if ( !table.isAbstractUnionTable() ) { - columns.addAll( table.getColumns() ); + else { + final Set columns = new LinkedHashSet<>(); + for ( var table : model.getSubclassTableClosure() ) { + if ( !table.isAbstractUnionTable() ) { + columns.addAll( table.getColumns() ); + } } - } - - final StringBuilder subquery = new StringBuilder() - .append( "(" ); - - final List classes = new JoinedList<>( - List.of( model ), - Collections.unmodifiableList( model.getSubclasses() ) - ); - - for ( PersistentClass clazz : classes ) { - Table table = clazz.getTable(); - if ( !table.isAbstractUnionTable() ) { - //TODO: move to .sql package!! - if ( subquery.length() > 1 ) { - subquery.append( " union " ); - if ( dialect.supportsUnionAll() ) { - subquery.append( "all " ); + final var dialect = factory.getJdbcServices().getDialect(); + final var subquery = new StringBuilder().append( "(" ); + final var classes = + new JoinedList<>( List.of( model ), + unmodifiableList( model.getSubclasses() ) ); + for ( var persistentClass : classes ) { + final var table = persistentClass.getTable(); + if ( !table.isAbstractUnionTable() ) { + //TODO: move to .sql package!! + if ( subquery.length() > 1 ) { + subquery.append( " union " ); + if ( dialect.supportsUnionAll() ) { + subquery.append( "all " ); + } } - } - subquery.append( "select " ); - for ( Column col : columns ) { - if ( !table.containsColumn( col ) ) { - subquery.append( getSelectClauseNullString( col, dialect ) ) - .append(" as "); + subquery.append( "select " ); + for ( var column : columns ) { + if ( !table.containsColumn( column ) ) { + subquery.append( getSelectClauseNullString( column, dialect ) ) + .append( " as " ); + } + subquery.append( column.getQuotedName( dialect ) ) + .append( ", " ); } - subquery.append( col.getQuotedName( dialect ) ) - .append(", "); + subquery.append( persistentClass.getSubclassId() ) + .append( " as clazz_ from " ) + .append( table.getQualifiedName( sqlStringGenerationContext ) ); } - subquery.append( clazz.getSubclassId() ) - .append( " as clazz_ from " ) - .append( table.getQualifiedName( getFactory().getSqlStringGenerationContext() ) ); } + return subquery.append( ")" ).toString(); } - - return subquery.append( ")" ).toString(); } - private String getSelectClauseNullString(Column col, Dialect dialect) { + private String getSelectClauseNullString(Column column, Dialect dialect) { return dialect.getSelectClauseNullString( new SqlTypedMappingImpl( - col.getTypeName(), - col.getLength(), - col.getArrayLength(), - col.getPrecision(), - col.getScale(), - col.getTemporalPrecision(), - col.getType() + column.getTypeName(), + column.getLength(), + column.getArrayLength(), + column.getPrecision(), + column.getScale(), + column.getTemporalPrecision(), + column.getType() ), getFactory().getTypeConfiguration() ); @@ -482,15 +474,15 @@ protected String generateSubquery(Map entityNameUses) { return getTableName(); } - final Dialect dialect = getFactory().getJdbcServices().getDialect(); - final MappingMetamodelImplementor metamodel = getFactory().getMappingMetamodel(); + final var factory = getFactory(); + final var dialect = factory.getJdbcServices().getDialect(); + final var metamodel = factory.getMappingMetamodel(); // Collect all selectables of every entity subtype and group by selection expression as well as table name final LinkedHashMap> selectables = new LinkedHashMap<>(); final Set tablesToUnion = new HashSet<>( entityNameUses.size() ); // Check if there are filter uses and if so, we know the set of tables to union already - for ( Map.Entry entry : entityNameUses.entrySet() ) { - final UnionSubclassEntityPersister persister = - (UnionSubclassEntityPersister) metamodel.getEntityDescriptor( entry.getKey() ); + for ( var entry : entityNameUses.entrySet() ) { + final var persister = (UnionSubclassEntityPersister) metamodel.getEntityDescriptor( entry.getKey() ); if ( entry.getValue().getKind() == EntityNameUse.UseKind.FILTER && !persister.isAbstract() ) { tablesToUnion.add( persister.getRootTableName() ); } @@ -500,11 +492,10 @@ protected String generateSubquery(Map entityNameUses) { if ( tablesToUnion.isEmpty() ) { // If there are no filter uses, we try to find the most specific treat uses and union all their subclass tables - for ( Map.Entry entry : entityNameUses.entrySet() ) { + for ( var entry : entityNameUses.entrySet() ) { if ( entry.getValue().getKind() == EntityNameUse.UseKind.TREAT ) { // Collect all the real (non-abstract) table names - final UnionSubclassEntityPersister persister = - (UnionSubclassEntityPersister) metamodel.getEntityDescriptor( entry.getKey() ); + final var persister = (UnionSubclassEntityPersister) metamodel.getEntityDescriptor( entry.getKey() ); tablesToUnion.addAll( Arrays.asList( persister.getConstraintOrderedTableNameClosure() ) ); } } @@ -514,77 +505,70 @@ protected String generateSubquery(Map entityNameUses) { } } - // Create a union sub-query for the table names, like generateSubquery(PersistentClass model, Mapping mapping) - final StringBuilder buf = new StringBuilder( subquery.length() ).append( "(" ); - - final Collection subMappingTypes = getSubMappingTypes(); - final ArrayList subMappingTypesAndThis = new ArrayList<>( subMappingTypes.size() + 1 ); + // Create a union subquery for the table names, + // like generateSubquery(PersistentClass model) + final var unionSubquery = new StringBuilder( subquery.length() ).append( "(" ); + final var typeConfiguration = factory.getTypeConfiguration(); + final var subMappingTypes = getSubMappingTypes(); + final ArrayList subMappingTypesAndThis = + new ArrayList<>( subMappingTypes.size() + 1 ); subMappingTypesAndThis.add( this ); subMappingTypesAndThis.addAll( subMappingTypes ); - for ( EntityMappingType mappingType : subMappingTypesAndThis ) { - final EntityPersister persister = (EntityPersister) mappingType; - final String subclassTableName; - if ( mappingType.hasSubclasses() ) { - subclassTableName = persister.getRootTableName(); - } - else { - subclassTableName = persister.getTableName(); - } + for ( var mappingType : subMappingTypesAndThis ) { + final var persister = (EntityPersister) mappingType; + final String subclassTableName = + mappingType.hasSubclasses() + ? persister.getRootTableName() + : persister.getTableName(); if ( tablesToUnion.contains( subclassTableName ) ) { - if ( buf.length() > 1 ) { - buf.append(" union "); + if ( unionSubquery.length() > 1 ) { + unionSubquery.append(" union "); if ( dialect.supportsUnionAll() ) { - buf.append("all "); + unionSubquery.append("all "); } } - buf.append( "select " ); - for ( Map selectableMappings : selectables.values() ) { - SelectableMapping selectableMapping = selectableMappings.get( subclassTableName ); + unionSubquery.append( "select " ); + for ( var selectableMappings : selectables.values() ) { + var selectableMapping = selectableMappings.get( subclassTableName ); if ( selectableMapping == null ) { // If there is no selectable mapping for a table name, we render a null expression selectableMapping = selectableMappings.values().iterator().next(); - buf.append( dialect.getSelectClauseNullString( selectableMapping, getFactory().getTypeConfiguration() ) ) + unionSubquery.append( dialect.getSelectClauseNullString( selectableMapping, typeConfiguration ) ) .append( " as " ); } if ( selectableMapping.isFormula() ) { - buf.append( selectableMapping.getSelectableName() ); + unionSubquery.append( selectableMapping.getSelectableName() ); } else { - buf.append( selectableMapping.getSelectionExpression() ); + unionSubquery.append( selectableMapping.getSelectionExpression() ); } - buf.append( ", " ); + unionSubquery.append( ", " ); } - buf.append( persister.getDiscriminatorSQLValue() ) + unionSubquery.append( persister.getDiscriminatorSQLValue() ) .append( " as clazz_ from " ) .append( subclassTableName ); } } - return buf.append( ")" ).toString(); + return unionSubquery.append( ")" ).toString(); } private void collectSelectableOwners(LinkedHashMap> selectables) { if ( !isAbstract() ) { final SelectableConsumer selectableConsumer = (i, selectable) -> { - Map selectableMapping = selectables.computeIfAbsent( + var selectableMapping = selectables.computeIfAbsent( selectable.getSelectionExpression(), k -> new HashMap<>() ); - final String subclassTableName; - if ( hasSubclasses() ) { - subclassTableName = getRootTableName(); - } - else { - subclassTableName = getTableName(); - } + final String subclassTableName = hasSubclasses() ? getRootTableName() : getTableName(); selectableMapping.put( subclassTableName, selectable ); }; getIdentifierMapping().forEachSelectable( selectableConsumer ); - if ( getVersionMapping() != null ) { - getVersionMapping().forEachSelectable( selectableConsumer ); + final var versionMapping = getVersionMapping(); + if ( versionMapping != null ) { + versionMapping.forEachSelectable( selectableConsumer ); } - final AttributeMappingsList attributeMappings = getAttributeMappings(); - final int size = attributeMappings.size(); - for ( int i = 0; i < size; i++ ) { + final var attributeMappings = getAttributeMappings(); + for ( int i = 0, size = attributeMappings.size(); i < size; i++ ) { attributeMappings.get( i ).forEachSelectable( selectableConsumer ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinatorStandard.java index 887435ece2d4..464def23a808 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinatorStandard.java @@ -38,7 +38,6 @@ import org.hibernate.sql.model.ast.builder.TableInsertBuilder; import org.hibernate.sql.model.ast.builder.TableInsertBuilderStandard; import org.hibernate.sql.model.ast.builder.TableMutationBuilder; -import org.hibernate.tuple.entity.EntityMetamodel; import org.checkerframework.checker.nullness.qual.Nullable; @@ -67,7 +66,7 @@ public InsertCoordinatorStandard(EntityPersister entityPersister, SessionFactory batchKey = new BasicBatchKey( entityPersister.getEntityName() + "#INSERT" ); } - if ( entityPersister.getEntityMetamodel().isDynamicInsert() ) { + if ( entityPersister.isDynamicInsert() ) { // the entity specified dynamic-insert - skip generating the // static inserts as we will create them every time staticInsertGroup = null; @@ -121,7 +120,7 @@ public GeneratedValues coordinateInsert( final boolean needsDynamicInsert = preInsertInMemoryValueGeneration( values, entity, session ); final EntityPersister persister = entityPersister(); final boolean forceIdentifierBinding = persister.getGenerator().generatedOnExecution() && id != null; - if ( persister.getEntityMetamodel().isDynamicInsert() + if ( persister.isDynamicInsert() || needsDynamicInsert || forceIdentifierBinding ) { return doDynamicInserts( id, values, entity, session, forceIdentifierBinding ); } @@ -132,10 +131,9 @@ public GeneratedValues coordinateInsert( protected boolean preInsertInMemoryValueGeneration(Object[] values, Object entity, SharedSessionContractImplementor session) { final EntityPersister persister = entityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); boolean foundStateDependentGenerator = false; - if ( entityMetamodel.hasPreInsertGeneratedValues() ) { - final Generator[] generators = entityMetamodel.getGenerators(); + if ( persister.hasPreInsertGeneratedProperties() ) { + final Generator[] generators = persister.getGenerators(); for ( int i = 0; i < generators.length; i++ ) { final Generator generator = generators[i]; if ( generator != null diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java index 367d53229aed..0d4a44374031 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java @@ -53,7 +53,6 @@ import org.hibernate.sql.model.ast.builder.TableUpdateBuilderStandard; import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; -import org.hibernate.tuple.entity.EntityMetamodel; import static org.hibernate.engine.OptimisticLockStyle.DIRTY; import static org.hibernate.engine.internal.Versioning.isVersionIncrementRequired; @@ -198,7 +197,7 @@ public GeneratedValues update( final boolean[] attributeUpdateability; boolean forceDynamicUpdate; - if ( entityPersister().getEntityMetamodel().isDynamicUpdate() && dirtyAttributeIndexes != null ) { + if ( entityPersister().isDynamicUpdate() && dirtyAttributeIndexes != null ) { attributeUpdateability = getPropertiesToUpdate( dirtyAttributeIndexes, hasDirtyCollection ); forceDynamicUpdate = true; } @@ -441,9 +440,9 @@ else if ( incomingDirtyAttributeIndexes != null ) { } private boolean hasUpdateGeneratedValues() { - final var entityMetamodel = entityPersister().getEntityMetamodel(); - return entityMetamodel.hasUpdateGeneratedValues() - || entityMetamodel.hasPreUpdateGeneratedValues(); + final var entityMetamodel = entityPersister(); + return entityMetamodel.hasUpdateGeneratedProperties() + || entityMetamodel.hasPreUpdateGeneratedProperties(); } private static boolean isValueGenerated(Generator generator) { @@ -542,8 +541,8 @@ private int[] preUpdateInMemoryValueGeneration( Object object, Object[] newValues, SharedSessionContractImplementor session) { - final EntityMetamodel entityMetamodel = entityPersister().getEntityMetamodel(); - if ( !entityMetamodel.hasPreUpdateGeneratedValues() ) { + final EntityPersister entityMetamodel = entityPersister(); + if ( !entityMetamodel.hasPreUpdateGeneratedProperties() ) { return EMPTY_INT_ARRAY; } @@ -909,7 +908,7 @@ else if ( entityPersister().isVersioned() && entityPersister().getVersionMapping().getVersionAttribute() == attributeMapping) { return true; } - else if ( entityPersister().getEntityMetamodel().isDynamicUpdate() && dirtinessChecker != null ) { + else if ( entityPersister().isDynamicUpdate() && dirtinessChecker != null ) { return attributeAnalysis.includeInSet() && dirtinessChecker.isDirty( attributeIndex, attributeMapping ).isDirty(); } @@ -1242,7 +1241,7 @@ else if ( versionMapping != null tableUpdateBuilder.addValueColumn( versionMapping.getVersionAttribute() ); } else { - final boolean includeInSet = !entityPersister().getEntityMetamodel().isDynamicUpdate() + final boolean includeInSet = !entityPersister().isDynamicUpdate() || dirtinessChecker == null || dirtinessChecker.isDirty( attributeIndex, attributeMapping ).isDirty(); if ( includeInSet ) { @@ -1327,7 +1326,7 @@ public UpdateValuesAnalysisImpl( tablesNeedingDynamicUpdate.add( tableMapping ); } else if ( dirtyAttributeIndexes != null ) { - if ( entityPersister().getEntityMetamodel().isDynamicUpdate() + if ( entityPersister().isDynamicUpdate() || entityPersister().optimisticLockStyle() == DIRTY ) { tablesNeedingDynamicUpdate.add( tableMapping ); } diff --git a/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java b/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java index a245069bfdb1..5840a16f1384 100644 --- a/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java @@ -345,7 +345,7 @@ public String getImplementationEntityName() { throw new LazyInitializationException( "Could not retrieve real entity name [" + entityName + "#" + id + "] - no session" ); } - if ( getEntityDescriptor().getEntityMetamodel().hasSubclasses() ) { + if ( getEntityDescriptor().hasSubclasses() ) { initialize(); return session.getFactory().bestGuessEntityName( target ); } diff --git a/hibernate-core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java b/hibernate-core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java index 3e5f1a6e8938..4d7399aae02f 100644 --- a/hibernate-core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java @@ -125,7 +125,7 @@ public Class getImplementationClass() { } final SessionFactoryImplementor factory = session.getFactory(); final EntityPersister entityDescriptor = factory.getMappingMetamodel().getEntityDescriptor( getEntityName() ); - if ( entityDescriptor.getEntityMetamodel().hasSubclasses() ) { + if ( entityDescriptor.hasSubclasses() ) { return getImplementation().getClass(); } return persistentClass; diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java index 4b92de3d23b7..c093d9d11ac7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java @@ -237,7 +237,7 @@ public JdbcValuesMapping resolve( if ( resultBuilders.size() == 1 && domainResults.size() == 1 && domainResults.get( 0 ) instanceof EntityResult entityResult ) { // Special case for result set mappings that just fetch a single polymorphic entity final EntityPersister persister = entityResult.getReferencedMappingContainer().getEntityPersister(); - final boolean polymorphic = persister.getEntityMetamodel().isPolymorphic(); + final boolean polymorphic = persister.isPolymorphic(); // We only need to check for duplicate aliases if we have join fetches, // otherwise we assume that even if there are duplicate aliases, the values are equivalent. // If we don't do that, there is no way to fetch joined inheritance entities diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 904781604411..70ffe5c70476 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -3110,7 +3110,7 @@ private void registerEntityNameUsage( } else { persister = creationContext.getMappingMetamodel().findEntityDescriptor( treatTargetTypeName ); - if ( persister == null || !persister.getEntityMetamodel().isPolymorphic() ) { + if ( persister == null || !persister.isPolymorphic() ) { return; } } @@ -5433,7 +5433,7 @@ private Set determineEmbeddableNamesForTreatTypeRestriction( private Predicate createTreatTypeRestriction(SqmPath lhs, EntityDomainType treatTarget) { final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( treatTarget.getHibernateEntityName() ); - if ( entityDescriptor.getEntityMetamodel().isPolymorphic() && lhs.getNodeType() != treatTarget ) { + if ( entityDescriptor.isPolymorphic() && lhs.getNodeType() != treatTarget ) { final Set subclassEntityNames = entityDescriptor.getSubclassEntityNames(); return createTreatTypeRestriction( lhs, subclassEntityNames ); } 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 29aafc2ef259..76e20bdcd486 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 @@ -20,7 +20,6 @@ import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.OnDeleteAction; import org.hibernate.boot.spi.MetadataImplementor; -import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataPojoImpl; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; @@ -35,18 +34,14 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Component; -import org.hibernate.mapping.GeneratorCreator; import org.hibernate.mapping.ManyToOne; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; -import org.hibernate.mapping.Subclass; -import org.hibernate.mapping.Value; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.tuple.IdentifierProperty; import org.hibernate.tuple.NonIdentifierAttribute; -import org.hibernate.tuple.PropertyFactory; import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; import org.hibernate.type.ComponentType; @@ -60,12 +55,15 @@ import static java.util.Collections.singleton; import static java.util.Collections.unmodifiableSet; +import static org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.includeInBaseFetchGroup; import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.util.ReflectHelper.isAbstractClass; import static org.hibernate.internal.util.ReflectHelper.isFinalClass; import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray; import static org.hibernate.internal.util.collections.CollectionHelper.toSmallSet; +import static org.hibernate.tuple.PropertyFactory.buildEntityBasedAttribute; import static org.hibernate.tuple.PropertyFactory.buildIdentifierAttribute; +import static org.hibernate.tuple.PropertyFactory.buildVersionProperty; /** * Centralizes metamodel information about an entity. @@ -85,7 +83,7 @@ public class EntityMetamodel implements Serializable { private final String name; private final String rootName; - private EntityType entityType; + private final EntityType entityType; private final int subclassId; private final IdentifierProperty identifierAttribute; @@ -154,9 +152,8 @@ public class EntityMetamodel implements Serializable { public EntityMetamodel( PersistentClass persistentClass, - EntityPersister persister, RuntimeModelCreationContext creationContext) { - this( persistentClass, persister, creationContext, + this( persistentClass, creationContext, rootName -> buildIdGenerator( rootName, persistentClass, creationContext ) ); } @@ -165,7 +162,6 @@ public EntityMetamodel( */ public EntityMetamodel( PersistentClass persistentClass, - EntityPersister persister, RuntimeModelCreationContext creationContext, Function generatorSupplier) { sessionFactory = creationContext.getSessionFactory(); @@ -174,48 +170,34 @@ public EntityMetamodel( name = persistentClass.getEntityName().intern(); rootName = persistentClass.getRootClass().getEntityName().intern(); // Make sure the hashCodes are cached + //noinspection ResultOfMethodCallIgnored name.hashCode(); + //noinspection ResultOfMethodCallIgnored rootName.hashCode(); + entityType = new ManyToOneType( name, creationContext.getTypeConfiguration() ); + subclassId = persistentClass.getSubclassId(); - final Generator idgenerator = generatorSupplier.apply( rootName ); - identifierAttribute = buildIdentifierAttribute( persistentClass, idgenerator ); + identifierAttribute = + buildIdentifierAttribute( + persistentClass, + generatorSupplier.apply( rootName ) + ); versioned = persistentClass.isVersioned(); - final boolean collectionsInDefaultFetchGroupEnabled = - creationContext.getSessionFactoryOptions().isCollectionsInDefaultFetchGroupEnabled(); - final boolean supportsCascadeDelete = creationContext.getDialect().supportsCascadeDelete(); + final boolean collectionsInDefaultFetchGroup = + creationContext.getSessionFactoryOptions() + .isCollectionsInDefaultFetchGroupEnabled(); - if ( persistentClass.hasPojoRepresentation() ) { - final Component identifierMapperComponent = persistentClass.getIdentifierMapper(); - final CompositeType nonAggregatedCidMapper; - final Set idAttributeNames; - if ( identifierMapperComponent != null ) { - nonAggregatedCidMapper = identifierMapperComponent.getType(); - HashSet tmpSet = new HashSet<>(); - for ( Property property : identifierMapperComponent.getProperties() ) { - tmpSet.add( property.getName() ); - } - idAttributeNames = toSmallSet( unmodifiableSet( tmpSet ) ); - } - else { - nonAggregatedCidMapper = null; - idAttributeNames = singleton( identifierAttribute.getName() ); - } - - bytecodeEnhancementMetadata = BytecodeEnhancementMetadataPojoImpl.from( - persistentClass, - idAttributeNames, - nonAggregatedCidMapper, - collectionsInDefaultFetchGroupEnabled, - creationContext.getMetadata() - ); - } - else { - bytecodeEnhancementMetadata = new BytecodeEnhancementMetadataNonPojoImpl( persistentClass.getEntityName() ); - } + bytecodeEnhancementMetadata = + bytecodeEnhancementMetadata( + persistentClass, + identifierAttribute, + creationContext, + collectionsInDefaultFetchGroup + ); boolean hasLazy = false; @@ -246,6 +228,8 @@ public EntityMetamodel( boolean foundPostUpdateGeneratedValues = false; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + final boolean supportsCascadeDelete = creationContext.getDialect().supportsCascadeDelete(); + int tempVersionProperty = NO_VERSION_INDX; boolean foundCascade = false; boolean foundToOne = false; @@ -258,30 +242,13 @@ public EntityMetamodel( boolean foundUpdateableNaturalIdProperty = false; BeforeExecutionGenerator tempVersionGenerator = null; - final List props = persistentClass.getPropertyClosure(); + final var props = persistentClass.getPropertyClosure(); for ( int i=0; i { - final MetadataImplementor metadata = creationContext.getMetadata(); - final PersistentClass entityBinding = metadata.getEntityBinding( entityName ); - assert entityBinding != null; - return entityBinding.hasSubclasses(); - }, - collectionsInDefaultFetchGroupEnabled - ); + final boolean lazy = + isLazy( creationContext, property, collectionsInDefaultFetchGroup, bytecodeEnhancementMetadata ); if ( lazy ) { hasLazy = true; } - propertyLaziness[i] = lazy; - propertyNames[i] = attribute.getName(); - final Type propertyType = attribute.getType(); + final var propertyType = attribute.getType(); propertyTypes[i] = propertyType; if ( attribute.isDirtyCheckable() && !( propertyType instanceof OneToOneType ) ) { dirtyCheckablePropertyTypes[i] = propertyType; @@ -327,14 +283,15 @@ public EntityMetamodel( propertyVersionability[i] = attribute.isVersionable(); nonlazyPropertyUpdateability[i] = attribute.isUpdateable() && !lazy; propertyCheckability[i] = propertyUpdateability[i] - || propertyType.isAssociationType() && ( (AssociationType) propertyType ).isAlwaysDirtyChecked(); + || propertyType instanceof AssociationType associationType + && associationType.isAlwaysDirtyChecked(); propertyOnDeleteActions[i] = supportsCascadeDelete ? attribute.getOnDeleteAction() : null; cascadeStyles[i] = attribute.getCascadeStyle(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // generated value strategies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - final Generator generator = buildGenerator( name, property, creationContext ); + final var generator = buildGenerator( name, property, creationContext ); if ( generator != null ) { final boolean generatedOnExecution = generator.generatedOnExecution(); if ( i == tempVersionProperty && !generatedOnExecution ) { @@ -394,18 +351,21 @@ else if ( !allowMutation ) { foundCascadeDelete = true; } - if ( indicatesToOne( attribute.getType() ) ) { + if ( indicatesToOne( propertyType ) ) { foundToOne = true; } - if ( indicatesCollection( attribute.getType() ) ) { + if ( indicatesCollection( propertyType ) ) { foundCollection = true; } - if ( indicatesOwnedCollection( attribute.getType(), creationContext.getMetadata() ) ) { + if ( indicatesOwnedCollection( propertyType, creationContext.getMetadata() ) ) { foundOwnedCollection = true; } - // Component types are dirty tracked as well so they are not exactly mutable for the "maybeDirty" check - if ( propertyType.isMutable() && propertyCheckability[i] && !( propertyType instanceof ComponentType ) ) { + // Component types are dirty-tracked as well, so they + // are not exactly mutable for the "maybeDirty" check + if ( propertyType.isMutable() + && propertyCheckability[i] + && !( propertyType instanceof ComponentType ) ) { mutableIndexes.set( i ); } @@ -441,38 +401,19 @@ else if ( !allowMutation ) { LOG.lazyPropertyFetchingAvailable( name ); } - lazy = persistentClass.isLazy() - // TODO: this disables laziness even in non-pojo entity modes: - && (!persistentClass.hasPojoRepresentation() || !isFinalClass( persistentClass.getProxyInterface() ) ) - || bytecodeEnhancementMetadata.isEnhancedForLazyLoading(); + lazy = isLazy( persistentClass, bytecodeEnhancementMetadata ); mutable = persistentClass.isMutable(); - if ( persistentClass.isAbstract() == null ) { - // legacy behavior (with no abstract attribute specified) - isAbstract = persistentClass.hasPojoRepresentation() - && isAbstractClass( persistentClass.getMappedClass() ); - } - else { - isAbstract = persistentClass.isAbstract(); - if ( !isAbstract - && persistentClass.hasPojoRepresentation() - && isAbstractClass( persistentClass.getMappedClass() ) ) { - LOG.entityMappedAsNonAbstract( name ); - } - } + isAbstract = isAbstract( persistentClass ); selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate(); - dynamicUpdate = persistentClass.useDynamicUpdate() - || ( getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() - && getBytecodeEnhancementMetadata().getLazyAttributesMetadata().getFetchGroupNames().size() > 1 ); + dynamicUpdate = persistentClass.useDynamicUpdate() || hasMultipleFetchGroups( bytecodeEnhancementMetadata ); dynamicInsert = persistentClass.useDynamicInsert(); polymorphic = persistentClass.isPolymorphic(); inherited = persistentClass.isInherited(); - superclass = inherited - ? persistentClass.getSuperclass().getEntityName() - : null; + superclass = inherited ? persistentClass.getSuperclass().getEntityName() : null; hasSubclasses = persistentClass.hasSubclasses(); optimisticLockStyle = persistentClass.getOptimisticLockStyle(); @@ -494,13 +435,7 @@ && isAbstractClass( persistentClass.getMappedClass() ) ) { hasOwnedCollections = foundOwnedCollection; mutablePropertiesIndexes = mutableIndexes; - // Need deterministic ordering - final Set subclassEntityNamesLocal = new LinkedHashSet<>(); - subclassEntityNamesLocal.add( name ); - for ( Subclass subclass : persistentClass.getSubclasses() ) { - subclassEntityNamesLocal.add( subclass.getEntityName() ); - } - subclassEntityNames = toSmallSet( subclassEntityNamesLocal ); + subclassEntityNames = collectSubclassEntityNames( persistentClass ); // HashMap, String> entityNameByInheritanceClassMapLocal = new HashMap<>(); // if ( persistentClass.hasPojoRepresentation() ) { @@ -512,6 +447,124 @@ && isAbstractClass( persistentClass.getMappedClass() ) ) { // entityNameByInheritanceClassMap = toSmallMap( entityNameByInheritanceClassMapLocal ); } + private Set collectSubclassEntityNames(PersistentClass persistentClass) { + final Set entityNames = new LinkedHashSet<>(); // Need deterministic ordering + entityNames.add( name ); + for ( var subclass : persistentClass.getSubclasses() ) { + entityNames.add( subclass.getEntityName() ); + } + return toSmallSet( entityNames ); + } + + private static boolean isAbstract(PersistentClass persistentClass) { + final Boolean isAbstract = persistentClass.isAbstract(); + if ( isAbstract == null ) { + // legacy behavior (with no abstract attribute specified) + return persistentClass.hasPojoRepresentation() + && isAbstractClass( persistentClass.getMappedClass() ); + } + else { + if ( !isAbstract + && persistentClass.hasPojoRepresentation() + && isAbstractClass( persistentClass.getMappedClass() ) ) { + LOG.entityMappedAsNonAbstract( persistentClass.getEntityName() ); + } + return isAbstract; + } + } + + //TODO: move this down to AbstractEntityPersister + private NonIdentifierAttribute buildAttribute( + PersistentClass persistentClass, + RuntimeModelCreationContext creationContext, + Property property, + int index) { + if ( property == persistentClass.getVersion() ) { + return buildVersionProperty( + (EntityPersister) this, + sessionFactory, + index, + property, + bytecodeEnhancementMetadata.isEnhancedForLazyLoading() + ); + } + else { + return buildEntityBasedAttribute( + (EntityPersister) this, + sessionFactory, + index, + property, + bytecodeEnhancementMetadata.isEnhancedForLazyLoading(), + creationContext + ); + } + } + + private boolean isLazy(PersistentClass persistentClass, BytecodeEnhancementMetadata enhancementMetadata) { + return persistentClass.isLazy() + // TODO: this disables laziness even in non-pojo entity modes: + && ( !persistentClass.hasPojoRepresentation() || !isFinalClass( persistentClass.getProxyInterface() ) ) + || enhancementMetadata.isEnhancedForLazyLoading(); + } + + private boolean hasMultipleFetchGroups(BytecodeEnhancementMetadata enhancementMetadata) { + return enhancementMetadata.isEnhancedForLazyLoading() + && enhancementMetadata.getLazyAttributesMetadata().getFetchGroupNames().size() > 1; + } + + private static boolean isLazy( + RuntimeModelCreationContext creationContext, + Property property, + boolean collectionsInDefaultFetchGroupEnabled, + BytecodeEnhancementMetadata enhancementMetadata) { + return !includeInBaseFetchGroup( + property, + enhancementMetadata.isEnhancedForLazyLoading(), + entityName -> { + final var entityBinding = + creationContext.getMetadata().getEntityBinding( entityName ); + assert entityBinding != null; + return entityBinding.hasSubclasses(); + }, + collectionsInDefaultFetchGroupEnabled + ); + } + + private static BytecodeEnhancementMetadata bytecodeEnhancementMetadata( + PersistentClass persistentClass, + IdentifierProperty identifierAttribute, + RuntimeModelCreationContext creationContext, + boolean collectionsInDefaultFetchGroupEnabled) { + if ( persistentClass.hasPojoRepresentation() ) { + final var identifierMapperComponent = persistentClass.getIdentifierMapper(); + final CompositeType nonAggregatedCidMapper; + final Set idAttributeNames; + if ( identifierMapperComponent != null ) { + nonAggregatedCidMapper = identifierMapperComponent.getType(); + final HashSet propertyNames = new HashSet<>(); + for ( var property : identifierMapperComponent.getProperties() ) { + propertyNames.add( property.getName() ); + } + idAttributeNames = toSmallSet( unmodifiableSet( propertyNames ) ); + } + else { + nonAggregatedCidMapper = null; + idAttributeNames = singleton( identifierAttribute.getName() ); + } + + return BytecodeEnhancementMetadataPojoImpl.from( + persistentClass, + idAttributeNames, + nonAggregatedCidMapper, + collectionsInDefaultFetchGroupEnabled, + creationContext.getMetadata() + ); + } + else { + return new BytecodeEnhancementMetadataNonPojoImpl( persistentClass.getEntityName() ); + } + } + private static boolean writePropertyValue(OnExecutionGenerator generator) { final boolean writePropertyValue = generator.writePropertyValue(); // TODO: move this validation somewhere else! @@ -522,12 +575,12 @@ private static boolean writePropertyValue(OnExecutionGenerator generator) { } private static Generator buildIdGenerator(String rootName, PersistentClass persistentClass, RuntimeModelCreationContext creationContext) { - final Generator existing = creationContext.getGenerators().get( rootName ); + final var existing = creationContext.getGenerators().get( rootName ); if ( existing != null ) { return existing; } else { - final Generator idgenerator = + final var idGenerator = persistentClass.getIdentifier() // returns the cached Generator if it was already created .createGenerator( @@ -536,13 +589,13 @@ private static Generator buildIdGenerator(String rootName, PersistentClass persi persistentClass.getIdentifierProperty(), creationContext.getGeneratorSettings() ); - creationContext.getGenerators().put( rootName, idgenerator ); - return idgenerator; + creationContext.getGenerators().put( rootName, idGenerator ); + return idGenerator; } } private void verifyNaturalIdProperty(Property property) { - final Value value = property.getValue(); + final var value = property.getValue(); if ( value instanceof ManyToOne toOne ) { if ( toOne.getNotFoundAction() == NotFoundAction.IGNORE ) { throw new MappingException( "Association '" + propertyName( property ) @@ -551,7 +604,7 @@ private void verifyNaturalIdProperty(Property property) { } } else if ( value instanceof Component component ) { - for ( Property componentProperty : component.getProperties() ) { + for ( var componentProperty : component.getProperties() ) { verifyNaturalIdProperty( componentProperty ); } } @@ -565,17 +618,17 @@ private static Generator buildGenerator( final String entityName, final Property mappingProperty, final RuntimeModelCreationContext context) { - final GeneratorCreator generatorCreator = mappingProperty.getValueGeneratorCreator(); + final var generatorCreator = mappingProperty.getValueGeneratorCreator(); if ( generatorCreator != null ) { - final Generator generator = mappingProperty.createGenerator( context ); + final var generator = mappingProperty.createGenerator( context ); if ( generator.generatesSometimes() ) { return generator; } } if ( mappingProperty.getValue() instanceof Component component ) { - final CompositeGeneratorBuilder builder = + final var builder = new CompositeGeneratorBuilder( entityName, mappingProperty, context.getDialect() ); - for ( Property property : component.getProperties() ) { + for ( var property : component.getProperties() ) { builder.add( property.createGenerator( context ) ); } return builder.build(); @@ -594,7 +647,7 @@ public BeforeExecutionGenerator getVersionGenerator() { private void mapPropertyToIndex(Property property, int i) { propertyIndexes.put( property.getName(), i ); if ( property.getValue() instanceof Component composite ) { - for ( Property subproperty : composite.getProperties() ) { + for ( var subproperty : composite.getProperties() ) { propertyIndexes.put( property.getName() + '.' + subproperty.getName(), i @@ -611,9 +664,11 @@ public boolean isNaturalIdentifierInsertGenerated() { if ( naturalIdPropertyNumbers.length == 0 ) { throw new IllegalStateException( "Entity '" + name + "' does not have a natural id" ); } - for ( int i = 0; i < naturalIdPropertyNumbers.length; i++ ) { - final Generator strategy = generators[ naturalIdPropertyNumbers[i] ]; - if ( strategy != null && strategy.generatesOnInsert() && strategy.generatedOnExecution() ) { + for ( int naturalIdPropertyNumber : naturalIdPropertyNumbers ) { + final var strategy = generators[naturalIdPropertyNumber]; + if ( strategy != null + && strategy.generatesOnInsert() + && strategy.generatedOnExecution() ) { return true; } } @@ -645,7 +700,7 @@ private static boolean indicatesToOne(Type type) { return true; } else if ( type instanceof CompositeType compositeType ) { - for ( Type subtype : compositeType.getSubtypes() ) { + for ( var subtype : compositeType.getSubtypes() ) { if ( indicatesToOne( subtype ) ) { return true; } @@ -659,7 +714,7 @@ private static boolean indicatesCollection(Type type) { return true; } else if ( type instanceof CompositeType compositeType ) { - for ( Type subtype : compositeType.getSubtypes() ) { + for ( var subtype : compositeType.getSubtypes() ) { if ( indicatesCollection( subtype ) ) { return true; } @@ -673,7 +728,7 @@ private static boolean indicatesOwnedCollection(Type type, MetadataImplementor m return !metadata.getCollectionBinding( collectionType.getRole() ).isInverse(); } else if ( type instanceof CompositeType compositeType ) { - for ( Type subtype : compositeType.getSubtypes() ) { + for ( var subtype : compositeType.getSubtypes() ) { if ( indicatesOwnedCollection( subtype, metadata ) ) { return true; } @@ -702,9 +757,6 @@ public int getSubclassId() { } public EntityType getEntityType() { - if ( entityType == null ) { - entityType = new ManyToOneType( name, getSessionFactory().getTypeConfiguration() ); - } return entityType; } @@ -721,12 +773,9 @@ public int getVersionPropertyIndex() { } public VersionProperty getVersionProperty() { - if ( NO_VERSION_INDX == versionPropertyIndex ) { - return null; - } - else { - return ( VersionProperty ) properties[ versionPropertyIndex ]; - } + return NO_VERSION_INDX == versionPropertyIndex + ? null + : (VersionProperty) properties[versionPropertyIndex]; } public NonIdentifierAttribute[] getProperties() { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusLazyGroupOnBasicFieldTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusLazyGroupOnBasicFieldTest.java index 3261638ad5f5..35d7c05255b6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusLazyGroupOnBasicFieldTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusLazyGroupOnBasicFieldTest.java @@ -56,7 +56,7 @@ public void tearDown(SessionFactoryScope scope) { public void test(SessionFactoryScope scope) { final EntityPersister persister = scope.getSessionFactory().getMappingMetamodel() .findEntityDescriptor( Person.class ); - assertThat( persister.getEntityMetamodel().isDynamicUpdate() ).isTrue(); + assertThat( persister.isDynamicUpdate() ).isTrue(); } @Test diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusSingleLazyGroupOnBasicFieldTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusSingleLazyGroupOnBasicFieldTest.java index 39198ecf90de..6468ef17bdbc 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusSingleLazyGroupOnBasicFieldTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusSingleLazyGroupOnBasicFieldTest.java @@ -56,7 +56,7 @@ public void tearDown(SessionFactoryScope scope) { public void test(SessionFactoryScope scope) { final EntityPersister persister = scope.getSessionFactory().getMappingMetamodel() .findEntityDescriptor( Person.class ); - assertThat( persister.getEntityMetamodel().isDynamicUpdate() ).isFalse(); + assertThat( persister.isDynamicUpdate() ).isFalse(); } @Test diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusWithMultipleToManyRelationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusWithMultipleToManyRelationTest.java index c6259b90de67..d817ebb9be4c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusWithMultipleToManyRelationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/dynamic/DynamicStatusWithMultipleToManyRelationTest.java @@ -42,7 +42,7 @@ public class DynamicStatusWithMultipleToManyRelationTest { public void test(SessionFactoryScope scope) { final EntityPersister persister = scope.getSessionFactory().getMappingMetamodel() .findEntityDescriptor( FooEntity.class ); - assertThat( persister.getEntityMetamodel().isDynamicUpdate() ).isFalse(); + assertThat( persister.isDynamicUpdate() ).isFalse(); } @Entity(name = "FooEntity") diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/BidirectionalLazyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/BidirectionalLazyTest.java index ee313455f55a..cafafe0d7404 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/BidirectionalLazyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/BidirectionalLazyTest.java @@ -274,7 +274,7 @@ private void checkEntityEntryState( final boolean isEmployerNullified) { final SessionImplementor sessionImplementor = (SessionImplementor) session; final EntityEntry entityEntry = sessionImplementor.getPersistenceContext().getEntry( employee ); - final int propertyNumber = entityEntry.getPersister().getEntityMetamodel().getPropertyIndex( "employer" ); + final int propertyNumber = entityEntry.getPersister().getPropertyIndex( "employer" ); assertEquals( employer, entityEntry.getLoadedState()[propertyNumber] diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java index 75e8875d7d1b..df3e1bf5ffbc 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bytecode/enhancement/lazy/proxy/SimpleUpdateWithLazyLoadingWithCollectionInDefaultFetchGroupFalseTest.java @@ -118,7 +118,7 @@ public void updateSimpleField(SessionFactoryScope scope) { .getMappingMetamodel() .getEntityDescriptor( Child.class.getName() ); - final int relativesAttributeIndex = childPersister.getEntityMetamodel().getPropertyIndex( "relatives" ); + final int relativesAttributeIndex = childPersister.getPropertyIndex( "relatives" ); scope.inTransaction( session -> { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java index 4fb902c35d82..d63fa2c006b1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java @@ -19,6 +19,7 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MappingException; +import org.hibernate.annotations.OnDeleteAction; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.cache.spi.access.CollectionDataAccess; @@ -34,6 +35,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.generator.Generator; import org.hibernate.generator.values.GeneratedValues; import org.hibernate.generator.values.GeneratedValuesMutationDelegate; import org.hibernate.id.IdentifierGenerator; @@ -375,7 +377,7 @@ public BasicType getVersionType() { } @Override - public int getVersionProperty() { + public int getVersionPropertyIndex() { return 0; } @@ -1062,6 +1064,61 @@ public void addSoftDeleteToInsertGroup(MutationGroupBuilder insertGroupBuilder) public String getAttributeMutationTableName(int i) { return ""; } + + @Override + public boolean isPolymorphic() { + return false; + } + + @Override + public boolean isDynamicUpdate() { + return false; + } + + @Override + public boolean isDynamicInsert() { + return false; + } + + @Override + public OnDeleteAction[] getPropertyOnDeleteActions() { + return new OnDeleteAction[0]; + } + + @Override + public Generator[] getGenerators() { + return new Generator[0]; + } + + @Override + public boolean hasImmutableNaturalId() { + return false; + } + + @Override + public boolean isNaturalIdentifierInsertGenerated() { + return false; + } + + @Override + public boolean isLazy() { + return false; + } + + @Override + public int getPropertySpan() { + return 0; + } + + @Override + public boolean hasPreInsertGeneratedProperties() { + return false; + } + + @Override + public boolean hasPreUpdateGeneratedProperties() { + return false; + } } public static class NoopCollectionPersister implements CollectionPersister { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java index 69a5c41a974f..7330c3be281c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java @@ -18,6 +18,7 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MappingException; +import org.hibernate.annotations.OnDeleteAction; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.cache.spi.access.EntityDataAccess; @@ -31,6 +32,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.generator.Generator; import org.hibernate.generator.values.GeneratedValues; import org.hibernate.generator.values.GeneratedValuesMutationDelegate; import org.hibernate.id.IdentifierGenerator; @@ -404,7 +406,7 @@ public BasicType getVersionType() { } @Override - public int getVersionProperty() { + public int getVersionPropertyIndex() { return 0; } @@ -1093,6 +1095,61 @@ public String getAttributeMutationTableName(int i) { public boolean managesColumns(String[] columnNames) { return false; } + + @Override + public boolean isPolymorphic() { + return false; + } + + @Override + public boolean isDynamicUpdate() { + return false; + } + + @Override + public boolean isDynamicInsert() { + return false; + } + + @Override + public OnDeleteAction[] getPropertyOnDeleteActions() { + return new OnDeleteAction[0]; + } + + @Override + public Generator[] getGenerators() { + return new Generator[0]; + } + + @Override + public boolean hasImmutableNaturalId() { + return false; + } + + @Override + public boolean isNaturalIdentifierInsertGenerated() { + return false; + } + + @Override + public boolean isLazy() { + return false; + } + + @Override + public int getPropertySpan() { + return 0; + } + + @Override + public boolean hasPreInsertGeneratedProperties() { + return false; + } + + @Override + public boolean hasPreUpdateGeneratedProperties() { + return false; + } } public static class GoofyException extends RuntimeException { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java index b6a629ad30a4..e1e33f51d697 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java @@ -83,13 +83,12 @@ import org.checkerframework.checker.nullness.qual.Nullable; -public class CustomPersister implements EntityPersister { +public class CustomPersister extends EntityMetamodel implements EntityPersister { private static final Hashtable INSTANCES = new Hashtable<>(); private static final IdentifierGenerator GENERATOR = new UUIDHexGenerator(); private final SessionFactoryImplementor factory; - private final EntityMetamodel entityMetamodel; @SuppressWarnings("UnusedParameters") public CustomPersister( @@ -97,8 +96,8 @@ public CustomPersister( EntityDataAccess cacheAccessStrategy, NaturalIdDataAccess naturalIdRegionAccessStrategy, RuntimeModelCreationContext creationContext) { + super( model, creationContext ); this.factory = creationContext.getSessionFactory(); - this.entityMetamodel = new EntityMetamodel( model, this, creationContext ); } public boolean hasLazyProperties() { @@ -424,9 +423,9 @@ public BasicType getVersionType() { } /** - * @see EntityPersister#getVersionProperty() + * @see EntityPersister#getVersionPropertyIndex() */ - public int getVersionProperty() { + public int getVersionPropertyIndex() { return 0; } @@ -511,7 +510,6 @@ public void lock( LockOptions lockOptions, SharedSessionContractImplementor session ) throws HibernateException { - throw new UnsupportedOperationException(); } @@ -525,7 +523,6 @@ public void lock( LockMode lockMode, SharedSessionContractImplementor session ) throws HibernateException { - throw new UnsupportedOperationException(); } @@ -829,7 +826,7 @@ public Serializable loadEntityIdByNaturalId(Object[] naturalIdValues, LockOption @Override public EntityMetamodel getEntityMetamodel() { - return entityMetamodel; + return this; } @Override @@ -1201,4 +1198,14 @@ public String getAttributeMutationTableName(int i) { public boolean managesColumns(String[] columnNames) { return false; } + + @Override + public boolean hasPreInsertGeneratedProperties() { + return false; + } + + @Override + public boolean hasPreUpdateGeneratedProperties() { + return false; + } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/cid/AbstractCompositeIdAndNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/cid/AbstractCompositeIdAndNaturalIdTest.java index 38bde5b99788..8d1f64fb50a5 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/cid/AbstractCompositeIdAndNaturalIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/cid/AbstractCompositeIdAndNaturalIdTest.java @@ -33,7 +33,7 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { assertThat( shortCodeMetadata.isNullable(), is( false ) ); final EntityPersister rootEntityPersister = accountMapping.getRootEntityDescriptor().getEntityPersister(); - final int shortCodeLegacyPropertyIndex = rootEntityPersister.getEntityMetamodel().getPropertyIndex( "shortCode" ); + final int shortCodeLegacyPropertyIndex = rootEntityPersister.getPropertyIndex( "shortCode" ); assertThat( shortCodeLegacyPropertyIndex, is ( 0 ) ); assertThat( rootEntityPersister.getPropertyNullability()[ shortCodeLegacyPropertyIndex ], is( false ) ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdAnnotationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdAnnotationTest.java index 646047e6a531..708405ff0067 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdAnnotationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdAnnotationTest.java @@ -10,7 +10,6 @@ import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.orm.junit.DomainModel; @@ -39,9 +38,8 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { final EntityMappingType childMapping = runtimeMetamodels.getEntityMappingType( Child.class.getName() ); final EntityPersister persister = childMapping.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); - final int nameIndex = entityMetamodel.getPropertyIndex( "name" ); - final int parentIndex = entityMetamodel.getPropertyIndex( "parent" ); + final int nameIndex = persister.getPropertyIndex( "name" ); + final int parentIndex = persister.getPropertyIndex( "parent" ); // checking alphabetic sort in relation to EntityPersister/EntityMetamodel assertThat( nameIndex, lessThan( parentIndex ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdHbmTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdHbmTest.java index b6a735fe4552..e1ea9f249471 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdHbmTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableManyToOneNaturalIdHbmTest.java @@ -13,7 +13,6 @@ import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.orm.junit.DomainModel; @@ -71,9 +70,8 @@ public void checkingMapping(SessionFactoryScope scope) { final EntityMappingType childMapping = runtimeMetamodels.getEntityMappingType( Child.class.getName() ); final EntityPersister persister = childMapping.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); - final int nameIndex = entityMetamodel.getPropertyIndex( "name" ); - final int parentIndex = entityMetamodel.getPropertyIndex( "parent" ); + final int nameIndex = persister.getPropertyIndex( "name" ); + final int parentIndex = persister.getPropertyIndex( "parent" ); // checking alphabetic sort in relation to EntityPersister/EntityMetamodel assertThat( nameIndex, lessThan( parentIndex ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableNaturalIdTest.java index dbc9efe24f3f..9247b2b91061 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableNaturalIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutable/ImmutableNaturalIdTest.java @@ -56,7 +56,7 @@ public void verifyMetamodel(SessionFactoryScope scope) { assertFalse( userNameMapping.getAttributeMetadata().isNullable() ); final EntityPersister persister = entityMappingType.getEntityPersister(); - final int propertyIndex = persister.getEntityMetamodel().getPropertyIndex( "userName" ); + final int propertyIndex = persister.getPropertyIndex( "userName" ); // nullability is not specified, so it should be non-nullable by hbm-specific default assertFalse( persister.getPropertyNullability()[propertyIndex] ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutableentity/ImmutableEntityNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutableentity/ImmutableEntityNaturalIdTest.java index 9084184ad17c..31363dd037ee 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutableentity/ImmutableEntityNaturalIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/immutableentity/ImmutableEntityNaturalIdTest.java @@ -13,7 +13,6 @@ import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.stat.spi.StatisticsImplementor; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.orm.junit.DomainModel; @@ -100,17 +99,16 @@ public void testNaturalIdMapping(SessionFactoryScope scope) { entityPersister.hasNaturalIdentifier(), is( true ) ); - final EntityMetamodel entityMetamodel = entityPersister.getEntityMetamodel(); assertThat( "Wrong number of attributes", - entityMetamodel.getNaturalIdentifierProperties().length, + entityPersister.getNaturalIdentifierProperties().length, is( 3 ) ); // nullability is not specified, so they should be nullable by annotations-specific default - assertTrue( entityPersister.getPropertyNullability()[ entityMetamodel.getPropertyIndex( "address" )] ); - assertTrue( entityPersister.getPropertyNullability()[ entityMetamodel.getPropertyIndex( "city" )] ); - assertTrue( entityPersister.getPropertyNullability()[ entityMetamodel.getPropertyIndex( "state" )] ); + assertTrue( entityPersister.getPropertyNullability()[ entityPersister.getPropertyIndex( "address" )] ); + assertTrue( entityPersister.getPropertyNullability()[ entityPersister.getPropertyIndex( "city" )] ); + assertTrue( entityPersister.getPropertyNullability()[ entityPersister.getPropertyIndex( "state" )] ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/inheritance/InheritedNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/inheritance/InheritedNaturalIdTest.java index b9ff6ec7c624..330ff49fbd65 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/inheritance/InheritedNaturalIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/inheritance/InheritedNaturalIdTest.java @@ -48,7 +48,7 @@ public void verifyMappingModel(SessionFactoryScope scope) { assertThat( uidMetadata.isNullable(), is( true ) ); final EntityPersister rootEntityPersister = userMapping.getEntityPersister(); - final int uidLegacyPropertyIndex = rootEntityPersister.getEntityMetamodel().getPropertyIndex( "uid" ); + final int uidLegacyPropertyIndex = rootEntityPersister.getPropertyIndex( "uid" ); assertThat( uidLegacyPropertyIndex, is ( 0 ) ); assertThat( rootEntityPersister.getPropertyNullability()[ uidLegacyPropertyIndex ], is( true ) ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/mutable/MutableNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/mutable/MutableNaturalIdTest.java index 7f6201fe6027..3ba806ab4839 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/mutable/MutableNaturalIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/mutable/MutableNaturalIdTest.java @@ -16,7 +16,6 @@ import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.Setting; -import org.hibernate.tuple.entity.EntityMetamodel; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -51,11 +50,10 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { final SessionFactoryImplementor sessionFactory = scope.getSessionFactory(); final EntityMappingType entityMappingType = sessionFactory.getRuntimeMetamodels().getEntityMappingType( User.class ); final EntityPersister persister = entityMappingType.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); // nullability is not specified, so it should be non-nullable by hbm-specific default - assertFalse( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "name" )] ); - assertFalse( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "org" )] ); + assertFalse( persister.getPropertyNullability()[persister.getPropertyIndex( "name" )] ); + assertFalse( persister.getPropertyNullability()[persister.getPropertyIndex( "org" )] ); } @AfterEach diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/nullable/NullableNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/nullable/NullableNaturalIdTest.java index f10c9c3d9b40..0c826b98bee6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/nullable/NullableNaturalIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/nullable/NullableNaturalIdTest.java @@ -8,7 +8,6 @@ import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.orm.junit.DomainModel; @@ -47,39 +46,37 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { final EntityMappingType entityMappingType = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType( A.class ); final NaturalIdMapping naturalIdMapping = entityMappingType.getNaturalIdMapping(); final EntityPersister persister = entityMappingType.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "assC" )] ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "myname" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "assC" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "myname" )] ); assertThat( naturalIdMapping.getNaturalIdAttributes().size(), is( 2 ) ); final SingularAttributeMapping firstAttribute = naturalIdMapping.getNaturalIdAttributes().get(0); assertThat( firstAttribute.getAttributeName(), is( "assC" ) ); - assertThat( firstAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "assC" ) ) ); + assertThat( firstAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "assC" ) ) ); final SingularAttributeMapping secondAttribute = naturalIdMapping.getNaturalIdAttributes().get(1); assertThat( secondAttribute.getAttributeName(), is( "myname" ) ); - assertThat( secondAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "myname" ) ) ); + assertThat( secondAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "myname" ) ) ); } { final EntityMappingType entityMappingType = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType( B.class ); final NaturalIdMapping naturalIdMapping = entityMappingType.getNaturalIdMapping(); final EntityPersister persister = entityMappingType.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "assA" )] ); - assertFalse( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "naturalid" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "assA" )] ); + assertFalse( persister.getPropertyNullability()[persister.getPropertyIndex( "naturalid" )] ); assertThat( naturalIdMapping.getNaturalIdAttributes().size(), is( 2 ) ); final SingularAttributeMapping firstAttribute = naturalIdMapping.getNaturalIdAttributes().get(0); assertThat( firstAttribute.getAttributeName(), is( "assA" ) ); - assertThat( firstAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "assA" ) ) ); + assertThat( firstAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "assA" ) ) ); assertTrue( firstAttribute.getAttributeMetadata().isNullable() ); final SingularAttributeMapping secondAttribute = naturalIdMapping.getNaturalIdAttributes().get(1); assertThat( secondAttribute.getAttributeName(), is( "naturalid" ) ); - assertThat( secondAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "naturalid" ) ) ); + assertThat( secondAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "naturalid" ) ) ); assertFalse( secondAttribute.getAttributeMetadata().isNullable() ); } @@ -87,13 +84,12 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { final EntityMappingType entityMappingType = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType( C.class ); final NaturalIdMapping naturalIdMapping = entityMappingType.getNaturalIdMapping(); final EntityPersister persister = entityMappingType.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); assertThat( naturalIdMapping.getNaturalIdAttributes().size(), is( 1 ) ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "name" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "name" )] ); final SingularAttributeMapping attribute = naturalIdMapping.getNaturalIdAttributes().get(0); - assertThat( attribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "name" ) ) ); + assertThat( attribute.getStateArrayPosition(), is( persister.getPropertyIndex( "name" ) ) ); assertTrue( attribute.getAttributeMetadata().isNullable() ); } @@ -101,20 +97,19 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { final EntityMappingType entityMappingType = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType( D.class ); final NaturalIdMapping naturalIdMapping = entityMappingType.getNaturalIdMapping(); final EntityPersister persister = entityMappingType.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); assertThat( naturalIdMapping.getNaturalIdAttributes().size(), is( 2 ) ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "associatedC" )] ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "name" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "associatedC" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "name" )] ); final SingularAttributeMapping firstAttribute = naturalIdMapping.getNaturalIdAttributes().get(0); assertThat( firstAttribute.getAttributeName(), is( "associatedC" ) ); - assertThat( firstAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "associatedC" ) ) ); + assertThat( firstAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "associatedC" ) ) ); assertTrue( firstAttribute.getAttributeMetadata().isNullable() ); final SingularAttributeMapping secondAttribute = naturalIdMapping.getNaturalIdAttributes().get(1); assertThat( secondAttribute.getAttributeName(), is( "name" ) ); - assertThat( secondAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "name" ) ) ); + assertThat( secondAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "name" ) ) ); assertTrue( secondAttribute.getAttributeMetadata().isNullable() ); } @@ -124,26 +119,25 @@ public void testNaturalIdNullability(SessionFactoryScope scope) { final EntityMappingType entityMappingType = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType( User.class ); final NaturalIdMapping naturalIdMapping = entityMappingType.getNaturalIdMapping(); final EntityPersister persister = entityMappingType.getEntityPersister(); - final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); assertThat( naturalIdMapping.getNaturalIdAttributes().size(), is( 3 ) ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "intVal" )] ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "name" )] ); - assertTrue( persister.getPropertyNullability()[entityMetamodel.getPropertyIndex( "org" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "intVal" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "name" )] ); + assertTrue( persister.getPropertyNullability()[persister.getPropertyIndex( "org" )] ); final SingularAttributeMapping firstAttribute = naturalIdMapping.getNaturalIdAttributes().get(0); assertThat( firstAttribute.getAttributeName(), is( "intVal" ) ); - assertThat( firstAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "intVal" ) ) ); + assertThat( firstAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "intVal" ) ) ); assertTrue( firstAttribute.getAttributeMetadata().isNullable() ); final SingularAttributeMapping secondAttribute = naturalIdMapping.getNaturalIdAttributes().get(1); assertThat( secondAttribute.getAttributeName(), is( "name" ) ); - assertThat( secondAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "name" ) ) ); + assertThat( secondAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "name" ) ) ); assertTrue( secondAttribute.getAttributeMetadata().isNullable() ); final SingularAttributeMapping thirdAttribute = naturalIdMapping.getNaturalIdAttributes().get(2); assertThat( thirdAttribute.getAttributeName(), is( "org" ) ); - assertThat( thirdAttribute.getStateArrayPosition(), is( entityMetamodel.getPropertyIndex( "org" ) ) ); + assertThat( thirdAttribute.getStateArrayPosition(), is( persister.getPropertyIndex( "org" ) ) ); assertTrue( thirdAttribute.getAttributeMetadata().isNullable() ); } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/validation/MockEntityPersister.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/validation/MockEntityPersister.java index 0557025955ea..e0a6b7fff9a0 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/validation/MockEntityPersister.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/validation/MockEntityPersister.java @@ -234,7 +234,7 @@ public String toString() { } @Override - public int getVersionProperty() { + public int getVersionPropertyIndex() { return 0; }