diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java index 7194d44cf498..d33dcd993745 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java @@ -3239,42 +3239,49 @@ private void bindManyToManyFilters( } for ( var filterSource : elementSource.getFilterSources() ) { - if ( filterSource.getName() == null ) { - if ( BOOT_LOGGER.isTraceEnabled() ) { - BOOT_LOGGER.tracef( - "Encountered filter with no name associated with many-to-many [%s]; skipping", - getPluralAttributeSource().getAttributeRole().getFullPath() - ); - } + bindManyToManyFilter( mappingDocument, collectionBinding, filterSource ); + } + } + + private void bindManyToManyFilter( + MappingDocument mappingDocument, Collection collectionBinding, FilterSource filterSource) { + final String name = filterSource.getName(); + if ( name == null ) { + if ( BOOT_LOGGER.isTraceEnabled() ) { + BOOT_LOGGER.tracef( + "Encountered filter with no name associated with many-to-many [%s]; skipping", + getPluralAttributeSource().getAttributeRole().getFullPath() + ); } - else { - if ( filterSource.getCondition() == null ) { - throw new MappingException( - String.format( - Locale.ENGLISH, - "No filter condition found for filter [%s] associated with many-to-many [%s]", - filterSource.getName(), - getPluralAttributeSource().getAttributeRole().getFullPath() - ), - mappingDocument.getOrigin() - ); - } - if ( BOOT_LOGGER.isTraceEnabled() ) { - BOOT_LOGGER.tracef( - "Applying many-to-many filter [%s] as [%s] to collection [%s]", - filterSource.getName(), - filterSource.getCondition(), - getPluralAttributeSource().getAttributeRole().getFullPath() - ); - } - collectionBinding.addManyToManyFilter( - filterSource.getName(), - filterSource.getCondition(), - filterSource.shouldAutoInjectAliases(), - filterSource.getAliasToTableMap(), - filterSource.getAliasToEntityMap() + } + else { + final String condition = filterSource.getCondition(); + if ( condition == null ) { + throw new MappingException( + String.format( + Locale.ENGLISH, + "No filter condition found for filter [%s] associated with many-to-many [%s]", + name, + getPluralAttributeSource().getAttributeRole().getFullPath() + ), + mappingDocument.getOrigin() ); } + if ( BOOT_LOGGER.isTraceEnabled() ) { + BOOT_LOGGER.tracef( + "Applying many-to-many filter [%s] as [%s] to collection [%s]", + name, + condition, + getPluralAttributeSource().getAttributeRole().getFullPath() + ); + } + collectionBinding.addManyToManyFilter( + name, + condition, + filterSource.shouldAutoInjectAliases(), + filterSource.getAliasToTableMap(), + filterSource.getAliasToEntityMap() + ); } } @@ -3451,10 +3458,9 @@ protected void createBackReferences() { && !collectionBinding.isInverse() && !indexIsFormula ) { final var oneToMany = (OneToMany) collectionBinding.getElement(); - final String entityName = oneToMany.getReferencedEntityName(); final var referenced = getMappingDocument().getMetadataCollector() - .getEntityBinding( entityName ); + .getEntityBinding( oneToMany.getReferencedEntityName() ); final var backref = new IndexBackref(); backref.setName( '_' + collectionBinding.getOwnerEntityName() + "." + getPluralAttributeSource().getName() + "IndexBackref" ); @@ -3533,10 +3539,9 @@ private void createIndexBackRef( && !collectionBinding.getKey().isNullable() && !collectionBinding.isInverse() ) { final var oneToMany = (OneToMany) collectionBinding.getElement(); - final String entityName = oneToMany.getReferencedEntityName(); final var referenced = mappingDocument.getMetadataCollector() - .getEntityBinding( entityName ); + .getEntityBinding( oneToMany.getReferencedEntityName() ); final var backref = new IndexBackref(); backref.setName( '_' + collectionBinding.getOwnerEntityName() + "." + pluralAttributeSource.getName() + "IndexBackref" ); diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementHelper.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementHelper.java index 2b072677721c..66920b662393 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementHelper.java @@ -32,28 +32,26 @@ public interface InheritanceChecker { * Should the given property be included in the owner's base fetch group? */ public static boolean includeInBaseFetchGroup( - Property bootMapping, + Property property, boolean isEnhanced, InheritanceChecker inheritanceChecker, boolean collectionsInDefaultFetchGroupEnabled) { - final var value = bootMapping.getValue(); - - if ( ! isEnhanced ) { - if ( value instanceof ToOne toOne ) { - if ( toOne.isUnwrapProxy() ) { - BYTECODE_INTERCEPTOR_LOGGER.toOneLazyNoProxyButNotEnhanced( - bootMapping.getPersistentClass().getEntityName(), - bootMapping.getName() - ); - } + final var value = property.getValue(); + + if ( !isEnhanced ) { + if ( value instanceof ToOne toOne && toOne.isUnwrapProxy() ) { + BYTECODE_INTERCEPTOR_LOGGER.toOneLazyNoProxyButNotEnhanced( + property.getPersistentClass().getEntityName(), + property.getName() + ); } return true; } // if we get here, we know the property owner is enhanced for laziness // - // NOTE : we make the (potentially untrue) assumption here that - // if the owner is enhanced, then all classes are enhanced.. + // NOTE: we make the (potentially untrue) assumption here that + // if the owner is enhanced, then all classes are enhanced. if ( value instanceof ToOne toOne ) { @@ -64,7 +62,7 @@ public static boolean includeInBaseFetchGroup( // it is lazy. see if we should select the FK - if ( bootMapping.getLazyGroup() != null ) { + if ( property.getLazyGroup() != null ) { // a non-base fetch group was explicitly specified // // really this should indicate to not select it as part of the base group. @@ -72,9 +70,9 @@ public static boolean includeInBaseFetchGroup( // we simply log a message that we are ignoring the `@LazyGroup` for to-ones BYTECODE_INTERCEPTOR_LOGGER.lazyGroupIgnoredForToOne( - bootMapping.getLazyGroup(), - bootMapping.getPersistentClass().getEntityName(), - bootMapping.getName() + property.getLazyGroup(), + property.getPersistentClass().getEntityName(), + property.getName() ); // at a later time - for example 6.0 when we can implement the join solution @@ -84,13 +82,13 @@ public static boolean includeInBaseFetchGroup( // for now, fall through } - if ( ! toOne.isReferenceToPrimaryKey() ) { + if ( !toOne.isReferenceToPrimaryKey() ) { // we do not have a reference to the associated primary-key return false; } if ( toOne.getColumnSpan() == 0 ) { - // generally this would indicate a "shared PK" on-to-one and there + // generally this would indicate a "shared PK" one-to-one and there // is no column for the association on the owner table - do not add // the association to the base group (which would force an immediate // select from the association table effectively making this @@ -98,15 +96,16 @@ public static boolean includeInBaseFetchGroup( return false; } - final boolean unwrapExplicitlyRequested = toOne.isUnwrapProxy() && !toOne.isUnwrapProxyImplicit(); + final boolean unwrapExplicitlyRequested = + toOne.isUnwrapProxy() && !toOne.isUnwrapProxyImplicit(); if ( inheritanceChecker.hasSubclasses( toOne.getReferencedEntityName() ) ) { // the associated type has subclasses - we cannot use the enhanced proxy and will generate a HibernateProxy if ( unwrapExplicitlyRequested ) { // NO_PROXY was explicitly requested BYTECODE_INTERCEPTOR_LOGGER.lazyNoProxyButAssociatedHasSubclasses( - bootMapping.getPersistentClass().getEntityName(), - bootMapping.getName(), + property.getPersistentClass().getEntityName(), + property.getName(), toOne.getReferencedEntityName() ); } @@ -117,8 +116,8 @@ public static boolean includeInBaseFetchGroup( if ( toOne instanceof ManyToOne manyToOne && manyToOne.isIgnoreNotFound() ) { if ( unwrapExplicitlyRequested ) { BYTECODE_INTERCEPTOR_LOGGER.notFoundIgnoreWithNoProxySkippingFkSelection( - bootMapping.getPersistentClass().getEntityName(), - bootMapping.getName() + property.getPersistentClass().getEntityName(), + property.getName() ); return false; } @@ -135,7 +134,7 @@ public static boolean includeInBaseFetchGroup( } return collectionsInDefaultFetchGroupEnabled && ( value instanceof Collection ) - || ! bootMapping.isLazy(); + || ! property.isLazy(); } public static T performWork( @@ -143,7 +142,7 @@ public static T performWork( BiFunction work, String entityName, String attributeName) { - SharedSessionContractImplementor session = interceptor.getLinkedSession(); + var session = interceptor.getLinkedSession(); final boolean isTempSession; final boolean isJta; @@ -236,23 +235,20 @@ enum Cause { NO_SF_UUID } - private static LazyInitializationException createLazyInitializationException(final Cause cause, final String entityName, final String attributeName) { - final String reason = switch ( cause ) { - case NO_SESSION -> "no session and settings disallow loading outside the Session"; - case CLOSED_SESSION -> "session is closed and settings disallow loading outside the Session"; - case DISCONNECTED_SESSION -> "session is disconnected and settings disallow loading outside the Session"; - case NO_SF_UUID -> "could not determine SessionFactory UUId to create temporary Session for loading"; - }; - - final String message = String.format( + private static LazyInitializationException createLazyInitializationException( + Cause cause, String entityName, String attributeName) { + return new LazyInitializationException( String.format( Locale.ROOT, "Unable to perform requested lazy initialization [%s.%s] - %s", entityName, attributeName, - reason - ); - - return new LazyInitializationException( message ); + switch ( cause ) { + case NO_SESSION -> "no session and settings disallow loading outside the Session"; + case CLOSED_SESSION -> "session is closed and settings disallow loading outside the Session"; + case DISCONNECTED_SESSION -> "session is disconnected and settings disallow loading outside the Session"; + case NO_SF_UUID -> "could not determine SessionFactory UUId to create temporary Session for loading"; + } + ) ); } private static SharedSessionContractImplementor openTemporarySessionForLoading( 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 c8536e8792b0..10677b67feb1 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 @@ -14,18 +14,14 @@ import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.bytecode.spi.NotInstrumentedException; -import org.hibernate.engine.spi.EntityEntry; -import org.hibernate.engine.spi.EntityHolder; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.ManagedEntity; -import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.SelfDirtinessTracker; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.Status; import org.hibernate.mapping.PersistentClass; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.CompositeType; import org.checkerframework.checker.nullness.qual.Nullable; @@ -50,9 +46,9 @@ public static BytecodeEnhancementMetadataPojoImpl from( CompositeType nonAggregatedCidMapper, boolean collectionsInDefaultFetchGroupEnabled, Metadata metadata) { - final Class mappedClass = persistentClass.getMappedClass(); + final var mappedClass = persistentClass.getMappedClass(); final boolean enhancedForLazyLoading = isPersistentAttributeInterceptableType( mappedClass ); - final LazyAttributesMetadata lazyAttributesMetadata = enhancedForLazyLoading + final var lazyAttributesMetadata = enhancedForLazyLoading ? LazyAttributesMetadata.from( persistentClass, true, collectionsInDefaultFetchGroupEnabled, metadata ) : LazyAttributesMetadata.nonEnhanced( persistentClass.getEntityName() ); @@ -139,7 +135,7 @@ public boolean isAttributeLoaded(Object entity, String attributeName) { return true; } - final BytecodeLazyAttributeInterceptor interceptor = extractLazyInterceptor( entity ); + final var interceptor = extractLazyInterceptor( entity ); if ( interceptor instanceof LazyAttributeLoadingInterceptor ) { return interceptor.isAttributeLoaded( attributeName ); } @@ -154,12 +150,12 @@ public boolean isAttributeLoaded(Object entity, String attributeName) { @Override public PersistentAttributeInterceptable createEnhancedProxy(EntityKey entityKey, boolean addEmptyEntry, SharedSessionContractImplementor session) { - final EntityPersister persister = entityKey.getPersister(); + final var persister = entityKey.getPersister(); final Object identifier = entityKey.getIdentifier(); - final PersistenceContext persistenceContext = session.getPersistenceContext(); + final var persistenceContext = session.getPersistenceContext(); // first, instantiate the entity instance to use as the proxy - final PersistentAttributeInterceptable entity = asPersistentAttributeInterceptable( persister.instantiate( identifier, session ) ); + final var entity = asPersistentAttributeInterceptable( persister.instantiate( identifier, session ) ); // clear the fields that are marked as dirty in the dirtiness tracker processIfSelfDirtinessTracker( entity, BytecodeEnhancementMetadataPojoImpl::clearDirtyAttributes ); @@ -170,8 +166,8 @@ public PersistentAttributeInterceptable createEnhancedProxy(EntityKey entityKey, // if requested, add the "holder entry" to the PC if ( addEmptyEntry ) { - EntityHolder entityHolder = persistenceContext.getEntityHolder( entityKey ); - EntityEntry entityEntry = persistenceContext.addEntry( + final var entityHolder = persistenceContext.getEntityHolder( entityKey ); + final var entityEntry = persistenceContext.addEntry( entity, Status.MANAGED, // loaded state @@ -223,14 +219,12 @@ public LazyAttributeLoadingInterceptor injectInterceptor( ) ); } - final LazyAttributeLoadingInterceptor interceptor = new LazyAttributeLoadingInterceptor( - this.lazyAttributeLoadingInterceptorState, + final var interceptor = new LazyAttributeLoadingInterceptor( + lazyAttributeLoadingInterceptorState, identifier, session ); - injectInterceptor( entity, interceptor, session ); - return interceptor; } @@ -257,10 +251,11 @@ public void injectEnhancedEntityAsProxyInterceptor( //This state object needs to be lazily initialized as it needs access to the Persister, but once //initialized it can be reused across multiple sessions. public EnhancementAsProxyLazinessInterceptor.EntityRelatedState getEnhancementAsProxyLazinessInterceptorMetastate(SharedSessionContractImplementor session) { - EnhancementAsProxyLazinessInterceptor.EntityRelatedState state = this.enhancementAsProxyInterceptorState; + var state = this.enhancementAsProxyInterceptorState; if ( state == null ) { - final EntityPersister entityPersister = session.getFactory().getMappingMetamodel() - .getEntityDescriptor( entityName ); + final var entityPersister = + session.getFactory().getMappingMetamodel() + .getEntityDescriptor( entityName ); state = new EnhancementAsProxyLazinessInterceptor.EntityRelatedState( entityPersister, nonAggregatedCidMapper, diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/CollectionEntry.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/CollectionEntry.java index f6981b79b4f3..f3ad3d7c9149 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/CollectionEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/CollectionEntry.java @@ -65,11 +65,9 @@ public CollectionEntry(CollectionPersister persister, PersistentCollection co // new collections that get found + wrapped // during flush shouldn't be ignored ignore = false; - // a newly wrapped collection is NOT dirty // (or we get unnecessary version updates) collection.clearDirty(); - snapshot = persister.isMutable() ? collection.getSnapshot( persister ) : null; role = persister.getRole(); collection.setSnapshot( loadedKey, role, snapshot ); @@ -84,16 +82,11 @@ public CollectionEntry( final Object loadedKey, final boolean ignore ) { this.ignore = ignore; - //collection.clearDirty() - this.loadedKey = loadedKey; - this.loadedPersister = loadedPersister; this.role = loadedPersister == null ? null : loadedPersister.getRole(); - collection.setSnapshot( loadedKey, role, null ); - //postInitialize() will be called after initialization } @@ -104,12 +97,10 @@ public CollectionEntry(CollectionPersister loadedPersister, Object loadedKey) { // detached collection wrappers that get found + reattached // during flush shouldn't be ignored ignore = false; - //collection.clearDirty() - this.loadedKey = loadedKey; this.loadedPersister = loadedPersister; - this.role = ( loadedPersister == null ? null : loadedPersister.getRole() ); + this.role = loadedPersister == null ? null : loadedPersister.getRole(); } /** @@ -119,11 +110,11 @@ public CollectionEntry(PersistentCollection collection, SessionFactoryImpleme // detached collections that get found + reattached // during flush shouldn't be ignored ignore = false; - loadedKey = collection.getKey(); role = collection.getRole(); - loadedPersister = factory.getMappingMetamodel().getCollectionDescriptor( castNonNull( role ) ); - + loadedPersister = + factory.getMappingMetamodel() + .getCollectionDescriptor( castNonNull( role ) ); snapshot = collection.getStoredSnapshot(); } @@ -151,53 +142,52 @@ private CollectionEntry( * of the collection elements, if necessary */ private void dirty(PersistentCollection collection) { - - final var loadedPersister = getLoadedPersister(); - final boolean forceDirty = - collection.wasInitialized() - && !collection.isDirty() //optimization - && loadedPersister != null - && loadedPersister.isMutable() //optimization - && ( collection.isDirectlyAccessible() || loadedPersister.getElementType().isMutable() ) //optimization - && !collection.equalsSnapshot( loadedPersister ); - if ( forceDirty ) { + if ( forceDirty( collection ) ) { collection.dirty(); } + } + private boolean forceDirty(PersistentCollection collection) { + final var loadedPersister = this.loadedPersister; + return collection.wasInitialized() + && !collection.isDirty() //optimization + && loadedPersister != null + && loadedPersister.isMutable() //optimization + && ( collection.isDirectlyAccessible() || loadedPersister.getElementType().isMutable() ) //optimization + && !collection.equalsSnapshot( loadedPersister ); } public void preFlush(PersistentCollection collection) { - if ( loadedKey == null && collection.getKey() != null ) { + if ( loadedKey == null ) { loadedKey = collection.getKey(); } - final var loadedPersister = getLoadedPersister(); - final boolean nonMutableChange = - collection.isDirty() - && loadedPersister != null - && !loadedPersister.isMutable(); - if ( nonMutableChange ) { + final var loadedPersister = this.loadedPersister; + if ( collection.isDirty() + && loadedPersister != null + && !loadedPersister.isMutable() ) { throw new HibernateException( "Immutable collection was modified: " + - collectionInfoString( castNonNull( loadedPersister ).getRole(), getLoadedKey() ) ); + collectionInfoString( loadedPersister.getRole(), getLoadedKey() ) ); } dirty( collection ); - if ( CORE_LOGGER.isTraceEnabled() && collection.isDirty() && loadedPersister != null ) { + if ( CORE_LOGGER.isTraceEnabled() + && loadedPersister != null + && collection.isDirty() ) { CORE_LOGGER.collectionDirty( collectionInfoString( loadedPersister.getRole(), getLoadedKey() ) ); } - setReached( false ); - setProcessed( false ); - - setDoupdate( false ); - setDoremove( false ); - setDorecreate( false ); + reached = false; + processed = false; + doupdate = false; + doremove = false; + dorecreate = false; } public void postInitialize(PersistentCollection collection, SharedSessionContractImplementor session) { - final var loadedPersister = getLoadedPersister(); + final var loadedPersister = this.loadedPersister; snapshot = loadedPersister != null && loadedPersister.isMutable() ? collection.getSnapshot( loadedPersister ) @@ -214,13 +204,11 @@ public void postInitialize(PersistentCollection collection, SharedSessionCont * Called after a successful flush */ public void postFlush(PersistentCollection collection) { - if ( isIgnore() ) { - ignore = false; - } - else if ( !isProcessed() ) { + if ( !ignore && !processed ) { throw new HibernateException( "Collection '" + collection.getRole() + "' was not processed by flush" + " (this is likely due to unsafe use of the session, for example, current use in multiple threads, or updates during entity lifecycle callbacks)"); } + ignore = false; collection.setSnapshot( loadedKey, role, snapshot ); } @@ -228,18 +216,17 @@ else if ( !isProcessed() ) { * Called after execution of an action */ public void afterAction(PersistentCollection collection) { - loadedKey = getCurrentKey(); - setLoadedPersister( getCurrentPersister() ); - + loadedKey = currentKey; + loadedPersister = currentPersister; + role = currentPersister == null ? null : currentPersister.getRole(); if ( collection.wasInitialized() - && ( isDoremove() || isDorecreate() || isDoupdate() ) ) { + && ( doremove || dorecreate || doupdate ) ) { // update the snapshot snapshot = loadedPersister != null && loadedPersister.isMutable() ? collection.getSnapshot( castNonNull( loadedPersister ) ) : null; } - collection.postAction(); } @@ -266,7 +253,6 @@ public void afterAction(PersistentCollection collection) { */ public void resetStoredSnapshot(PersistentCollection collection, Serializable storedSnapshot) { CORE_LOGGER.resetStoredSnapshot( storedSnapshot, this ); - if ( !fromMerge ) { snapshot = storedSnapshot; collection.setSnapshot( loadedKey, role, snapshot ); @@ -274,11 +260,6 @@ public void resetStoredSnapshot(PersistentCollection collection, Serializable } } - private void setLoadedPersister(@Nullable CollectionPersister persister) { - loadedPersister = persister; - setRole( persister == null ? null : persister.getRole() ); - } - void afterDeserialize(@Nullable SessionFactoryImplementor factory) { loadedPersister = factory == null ? null : factory.getMappingMetamodel() @@ -286,7 +267,7 @@ void afterDeserialize(@Nullable SessionFactoryImplementor factory) { } public boolean wasDereferenced() { - return getLoadedKey() == null; + return loadedKey == null; } public boolean isReached() { @@ -370,13 +351,13 @@ public void setRole(@Nullable String role) { @Override public String toString() { - final StringBuilder result = + final var result = new StringBuilder( "CollectionEntry" ) .append( collectionInfoString( role, loadedKey ) ); - final CollectionPersister persister = currentPersister; - if ( persister != null ) { + final var currentPersister = this.currentPersister; + if ( currentPersister != null ) { result.append( "->" ) - .append( collectionInfoString( persister.getRole(), currentKey ) ); + .append( collectionInfoString( currentPersister.getRole(), currentKey ) ); } return result.toString(); } @@ -395,11 +376,9 @@ public boolean isSnapshotEmpty(PersistentCollection collection) { //TODO: does this really need to be here? // does the collection already have // it's own up-to-date snapshot? - final var loadedPersister = getLoadedPersister(); - final Serializable snapshot = getSnapshot(); return collection.wasInitialized() && ( loadedPersister == null || loadedPersister.isMutable() ) - && ( snapshot == null || collection.isSnapshotEmpty(snapshot) ); + && ( snapshot == null || collection.isSnapshotEmpty( snapshot ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java index d8eb504ad3f6..9819b2cdb036 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/DirtyHelper.java @@ -96,9 +96,7 @@ public static int[] findDirty( int[] results = null; int count = 0; int span = propertyTypes.length; - for ( int i = 0; i < span; i++ ) { - if ( isDirty( propertyTypes, currentState, previousState, includeColumns, session, i ) ) { if ( results == null ) { results = new int[span]; @@ -106,7 +104,6 @@ public static int[] findDirty( results[count++] = i; } } - return count == 0 ? null : ArrayHelper.trim( results, count ); } diff --git a/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java b/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java index 395b82a12bb0..8df8b1326eac 100644 --- a/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java +++ b/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java @@ -10,7 +10,8 @@ /** * Allows programmatic {@linkplain #exportMappedObjects schema export}, * {@linkplain #validateMappedObjects schema validation}, - * {@linkplain #truncateMappedObjects data cleanup}, and + * {@linkplain #truncateMappedObjects data cleanup}, + * {@linkplain #populate data population}, and * {@linkplain #dropMappedObjects schema cleanup} as a convenience for * writing tests. * diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java index ddaa61cdb263..79fe41043f8c 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -4,10 +4,6 @@ */ package org.hibernate.tuple; -import org.hibernate.HibernateException; -import org.hibernate.boot.spi.MetadataImplementor; -import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.generator.Generator; import org.hibernate.mapping.PersistentClass; @@ -26,6 +22,8 @@ import org.hibernate.type.EntityType; import org.hibernate.type.Type; +import static org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.includeInBaseFetchGroup; + /** * @deprecated No direct replacement */ @@ -45,9 +43,8 @@ private PropertyFactory() { public static IdentifierProperty buildIdentifierAttribute( PersistentClass mappedEntity, Generator generator) { - Type type = mappedEntity.getIdentifier().getType(); - Property property = mappedEntity.getIdentifierProperty(); - + final var type = mappedEntity.getIdentifier().getType(); + final var property = mappedEntity.getIdentifierProperty(); if ( property == null ) { // this is a virtual id property... return new IdentifierProperty( @@ -82,9 +79,7 @@ public static VersionProperty buildVersionProperty( int attributeNumber, Property property, boolean lazyAvailable) { - - boolean lazy = lazyAvailable && property.isLazy(); - + final boolean lazy = lazyAvailable && property.isLazy(); return new VersionProperty( persister, sessionFactory, @@ -127,9 +122,7 @@ public static NonIdentifierAttribute buildEntityBasedAttribute( Property property, boolean lazyAvailable, RuntimeModelCreationContext creationContext) { - final Type type = property.getValue().getType(); - - final NonIdentifierAttributeNature nature = decode( type ); + final var type = property.getValue().getType(); // we need to dirty check collections, since they can cause an owner // version number increment @@ -138,89 +131,82 @@ public static NonIdentifierAttribute buildEntityBasedAttribute( // to update the cache (not the database), since in this case a null // entity reference can lose information - boolean alwaysDirtyCheck = type.isAssociationType() + final boolean alwaysDirtyCheck = type.isAssociationType() && ( (AssociationType) type ).isAlwaysDirtyChecked(); - SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions(); - final boolean lazy = ! EnhancementHelper.includeInBaseFetchGroup( + final boolean lazy = !includeInBaseFetchGroup( property, lazyAvailable, entityName -> { - final MetadataImplementor metadata = creationContext.getMetadata(); - final PersistentClass entityBinding = metadata.getEntityBinding( entityName ); + final var entityBinding = + creationContext.getMetadata() + .getEntityBinding( entityName ); assert entityBinding != null; return entityBinding.hasSubclasses(); }, - sessionFactoryOptions.isCollectionsInDefaultFetchGroupEnabled() + sessionFactory.getSessionFactoryOptions() + .isCollectionsInDefaultFetchGroupEnabled() ); - switch ( nature ) { - case BASIC: { - return new EntityBasedBasicAttribute( - persister, - sessionFactory, - attributeNumber, - property.getName(), - type, - new BaselineAttributeInformation.Builder() - .setLazy( lazy ) - .setInsertable( property.isInsertable() ) - .setUpdateable( property.isUpdatable() ) - .setNullable( property.isOptional() ) - .setDirtyCheckable( alwaysDirtyCheck || property.isUpdatable() ) - .setVersionable( property.isOptimisticLocked() ) - .setCascadeStyle( property.getCascadeStyle() ) - .setOnDeleteAction( property.getOnDeleteAction() ) - .setFetchMode( property.getValue().getFetchMode() ) - .createInformation() - ); - } - case COMPOSITE: { - return new EntityBasedCompositionAttribute( - persister, - sessionFactory, - attributeNumber, - property.getName(), - (CompositeType) type, - new BaselineAttributeInformation.Builder() - .setLazy( lazy ) - .setInsertable( property.isInsertable() ) - .setUpdateable( property.isUpdatable() ) - .setNullable( property.isOptional() ) - .setDirtyCheckable( alwaysDirtyCheck || property.isUpdatable() ) - .setVersionable( property.isOptimisticLocked() ) - .setCascadeStyle( property.getCascadeStyle() ) - .setOnDeleteAction( property.getOnDeleteAction() ) - .setFetchMode( property.getValue().getFetchMode() ) - .createInformation() - ); - } - case ENTITY: - case ANY: - case COLLECTION: { - return new EntityBasedAssociationAttribute( - persister, - sessionFactory, - attributeNumber, - property.getName(), - (AssociationType) type, - new BaselineAttributeInformation.Builder() - .setLazy( lazy ) - .setInsertable( property.isInsertable() ) - .setUpdateable( property.isUpdatable() ) - .setNullable( property.isOptional() ) - .setDirtyCheckable( alwaysDirtyCheck || property.isUpdatable() ) - .setVersionable( property.isOptimisticLocked() ) - .setCascadeStyle( property.getCascadeStyle() ) - .setOnDeleteAction( property.getOnDeleteAction() ) - .setFetchMode( property.getValue().getFetchMode() ) - .createInformation() - ); - } - default: { - throw new HibernateException( "Internal error" ); - } - } + return switch ( decode( type ) ) { + case BASIC -> + new EntityBasedBasicAttribute( + persister, + sessionFactory, + attributeNumber, + property.getName(), + type, + new BaselineAttributeInformation.Builder() + .setLazy( lazy ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdatable() ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( alwaysDirtyCheck || property.isUpdatable() ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .setOnDeleteAction( property.getOnDeleteAction() ) + .setFetchMode( property.getValue().getFetchMode() ) + .createInformation() + ); + case COMPOSITE -> + new EntityBasedCompositionAttribute( + persister, + sessionFactory, + attributeNumber, + property.getName(), + (CompositeType) type, + new BaselineAttributeInformation.Builder() + .setLazy( lazy ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdatable() ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( alwaysDirtyCheck || property.isUpdatable() ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .setOnDeleteAction( property.getOnDeleteAction() ) + .setFetchMode( property.getValue().getFetchMode() ) + .createInformation() + ); + case ENTITY, ANY, COLLECTION -> + new EntityBasedAssociationAttribute( + persister, + sessionFactory, + attributeNumber, + property.getName(), + (AssociationType) type, + new BaselineAttributeInformation.Builder() + .setLazy( lazy ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdatable() ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( alwaysDirtyCheck || property.isUpdatable() ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .setOnDeleteAction( property.getOnDeleteAction() ) + .setFetchMode( property.getValue().getFetchMode() ) + .createInformation() + ); + }; } private static NonIdentifierAttributeNature decode(Type type) { @@ -240,5 +226,4 @@ else if ( type instanceof ComponentType ) { return NonIdentifierAttributeNature.BASIC; } } - }