Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ public static BytecodeEnhancementMetadata from(
this.identifierAttributeNames = identifierAttributeNames;
this.enhancedForLazyLoading = enhancedForLazyLoading;
this.lazyAttributesMetadata = lazyAttributesMetadata;
this.lazyAttributeLoadingInterceptorState = new LazyAttributeLoadingInterceptor.EntityRelatedState(
getEntityName(), lazyAttributesMetadata.getLazyAttributeNames() );
this.lazyAttributeLoadingInterceptorState =
new LazyAttributeLoadingInterceptor.EntityRelatedState( getEntityName(),
lazyAttributesMetadata.getLazyAttributeNames() );
}

@Override
Expand All @@ -116,7 +117,7 @@ public boolean hasUnFetchedAttributes(Object entity) {
return false;
}

final BytecodeLazyAttributeInterceptor interceptor = extractLazyInterceptor( entity );
final var interceptor = extractLazyInterceptor( entity );
if ( interceptor instanceof LazyAttributeLoadingInterceptor ) {
return interceptor.hasAnyUninitializedAttributes();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
*/
package org.hibernate.bytecode.internal;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;

Expand All @@ -30,7 +28,7 @@ public final class BytecodeProviderInitiator implements StandardServiceInitiator

@Override
public BytecodeProvider initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
final Collection<BytecodeProvider> bytecodeProviders =
final var bytecodeProviders =
registry.requireService( ClassLoaderService.class )
.loadJavaServices( BytecodeProvider.class );
return getBytecodeProvider( bytecodeProviders );
Expand All @@ -52,16 +50,18 @@ public static BytecodeProvider buildDefaultBytecodeProvider() {

@Internal
public static BytecodeProvider getBytecodeProvider(Iterable<BytecodeProvider> bytecodeProviders) {
final Iterator<BytecodeProvider> iterator = bytecodeProviders.iterator();
final var iterator = bytecodeProviders.iterator();
if ( !iterator.hasNext() ) {
// If no BytecodeProvider service is available, default to the "no-op" enhancer
return new org.hibernate.bytecode.internal.none.BytecodeProviderImpl();
}

final BytecodeProvider provider = iterator.next();
if ( iterator.hasNext() ) {
throw new IllegalStateException( "Found multiple BytecodeProvider service registrations, cannot determine which one to use" );
else {
final var provider = iterator.next();
if ( iterator.hasNext() ) {
throw new IllegalStateException(
"Found multiple BytecodeProvider service registrations, cannot determine which one to use" );
}
return provider;
}
return provider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package org.hibernate.event.internal;

import java.lang.invoke.MethodHandles;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
Expand All @@ -15,7 +16,6 @@
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.spi.ActionQueue;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.CollectionKey;
Expand Down Expand Up @@ -143,30 +143,30 @@ void checkForTransientReferences(EventSource session, PersistenceContext persist
// processed, so that all entities which will be persisted are
// persistent when we do the check (I wonder if we could move this
// into Nullability, instead of abusing the Cascade infrastructure)
for ( var me : persistenceContext.reentrantSafeEntityEntries() ) {
final var entry = me.getValue();
for ( var entryEntry : persistenceContext.reentrantSafeEntityEntries() ) {
final var entry = entryEntry.getValue();
if ( checkable( entry ) ) {
Cascade.cascade(
CascadingActions.CHECK_ON_FLUSH,
CascadePoint.BEFORE_FLUSH,
session,
entry.getPersister(),
me.getKey(),
entryEntry.getKey(),
null
);
}
}
}

private static boolean flushable(EntityEntry entry) {
final Status status = entry.getStatus();
final var status = entry.getStatus();
return status == Status.MANAGED
|| status == Status.SAVING
|| status == Status.READ_ONLY; // debatable, see HHH-19398
}

private static boolean checkable(EntityEntry entry) {
final Status status = entry.getStatus();
final var status = entry.getStatus();
return status == Status.MANAGED
|| status == Status.SAVING;
}
Expand Down Expand Up @@ -228,7 +228,7 @@ private int flushEntities(final FlushEvent event, final PersistenceContext persi
for ( var me : entityEntries ) {
// Update the status of the object and if necessary, schedule an update
final var entry = me.getValue();
final Status status = entry.getStatus();
final var status = entry.getStatus();
if ( status != Status.LOADING && status != Status.GONE ) {
entityEvent = createOrReuseEventInstance( entityEvent, source, me.getKey(), entry );
entityEvent.setInstanceGenerationId( ++eventGenerationId );
Expand Down Expand Up @@ -270,74 +270,62 @@ private int flushCollections(final EventSource session, final PersistenceContext
throws HibernateException {
LOG.trace( "Processing unreferenced collections" );
final var collectionEntries = persistenceContext.getCollectionEntries();
final int count;
if ( collectionEntries == null ) {
count = 0;
}
else {
count = collectionEntries.size();
final var identityMap =
(InstanceIdentityMap<PersistentCollection<?>, CollectionEntry>)
collectionEntries;
for ( var me : identityMap.toArray() ) {
final var ce = me.getValue();
if ( !ce.isReached() && !ce.isIgnore() ) {
processUnreachableCollection( me.getKey(), session );
}
}
}
final int count = processUnreachableCollections( session, collectionEntries );

// Schedule updates to collections:

LOG.trace( "Scheduling collection removes/(re)creates/updates" );
final var actionQueue = session.getActionQueue();
final var interceptor = session.getInterceptor();
persistenceContext.forEachCollectionEntry(
(coll, ce) -> {
if ( ce.isDorecreate() ) {
interceptor.onCollectionRecreate( coll, ce.getCurrentKey() );
(collection, collectionEntry) -> {
if ( collectionEntry.isDorecreate() ) {
final var currentKey = collectionEntry.getCurrentKey();
interceptor.onCollectionRecreate( collection, currentKey );
actionQueue.addAction(
new CollectionRecreateAction(
coll,
ce.getCurrentPersister(),
ce.getCurrentKey(),
collection,
collectionEntry.getCurrentPersister(),
currentKey,
session
)
);
}
if ( ce.isDoremove() ) {
interceptor.onCollectionRemove( coll, ce.getLoadedKey() );
if ( !skipRemoval( session, ce.getLoadedPersister(), ce.getLoadedKey() ) ) {
if ( collectionEntry.isDoremove() ) {
final var loadedKey = collectionEntry.getLoadedKey();
interceptor.onCollectionRemove( collection, loadedKey );
if ( !skipRemoval( session, collectionEntry.getLoadedPersister(), loadedKey ) ) {
actionQueue.addAction(
new CollectionRemoveAction(
coll,
ce.getLoadedPersister(),
ce.getLoadedKey(),
ce.isSnapshotEmpty( coll ),
collection,
collectionEntry.getLoadedPersister(),
loadedKey,
collectionEntry.isSnapshotEmpty( collection ),
session
)
);
}
}
if ( ce.isDoupdate() ) {
interceptor.onCollectionUpdate( coll, ce.getLoadedKey() );
if ( collectionEntry.isDoupdate() ) {
final var loadedKey = collectionEntry.getLoadedKey();
interceptor.onCollectionUpdate( collection, loadedKey );
actionQueue.addAction(
new CollectionUpdateAction(
coll,
ce.getLoadedPersister(),
ce.getLoadedKey(),
ce.isSnapshotEmpty( coll ),
collection,
collectionEntry.getLoadedPersister(),
loadedKey,
collectionEntry.isSnapshotEmpty( collection ),
session
)
);
}
// todo : I'm not sure the !wasInitialized part should really be part of this check
if ( !coll.wasInitialized() && coll.hasQueuedOperations() ) {
if ( !collection.wasInitialized() && collection.hasQueuedOperations() ) {
actionQueue.addAction(
new QueuedOperationCollectionAction(
coll,
ce.getLoadedPersister(),
ce.getLoadedKey(),
collection,
collectionEntry.getLoadedPersister(),
collectionEntry.getLoadedKey(),
session
)
);
Expand All @@ -349,6 +337,27 @@ private int flushCollections(final EventSource session, final PersistenceContext
return count;
}

private static int processUnreachableCollections(
EventSource session,
Map<PersistentCollection<?>, CollectionEntry> collectionEntries) {
if ( collectionEntries == null ) {
return 0;
}
else {
final int count = collectionEntries.size();
final var identityMap =
(InstanceIdentityMap<PersistentCollection<?>, CollectionEntry>)
collectionEntries;
for ( var entry : identityMap.toArray() ) {
final var collectionEntry = entry.getValue();
if ( !collectionEntry.isReached() && !collectionEntry.isIgnore() ) {
processUnreachableCollection( entry.getKey(), session );
}
}
return count;
}
}

/**
* Execute all SQL (and second-level cache updates) in a special order so that foreign-key constraints cannot
* be violated: <ol>
Expand All @@ -375,7 +384,7 @@ protected void performExecutions(EventSource session) {
persistenceContext.setFlushing( true );
// we need to lock the collection caches before executing entity inserts/updates
// in order to account for bidirectional associations
final ActionQueue actionQueue = session.getActionQueue();
final var actionQueue = session.getActionQueue();
actionQueue.prepareActions();
actionQueue.executeActions();
}
Expand Down Expand Up @@ -410,26 +419,27 @@ protected void postFlush(SessionImplementor session) throws HibernateException {
persistenceContext.forEachCollectionEntry(
(persistentCollection, collectionEntry) -> {
collectionEntry.postFlush( persistentCollection );
final Object key;
if ( collectionEntry.getLoadedPersister() == null || ( key = collectionEntry.getLoadedKey() ) == null ) {
final var loadedPersister = collectionEntry.getLoadedPersister();
final Object key = collectionEntry.getLoadedKey();
if ( loadedPersister != null && key != null ) {
//otherwise recreate the mapping between the collection and its key
final var collectionKey = new CollectionKey( loadedPersister, key );
persistenceContext.addCollectionByKey( collectionKey, persistentCollection );
}
else {
//if the collection is dereferenced, unset its session reference and remove from the session cache
//iter.remove(); //does not work, since the entrySet is not backed by the set
persistentCollection.unsetSession( session );
persistenceContext.removeCollectionEntry( persistentCollection );
}
else {
//otherwise recreate the mapping between the collection and its key
final CollectionKey collectionKey =
new CollectionKey( collectionEntry.getLoadedPersister(), key );
persistenceContext.addCollectionByKey( collectionKey, persistentCollection );
}
},
true
);
}

protected void postPostFlush(SessionImplementor session) {
session.getInterceptor().postFlush( session.getPersistenceContextInternal().managedEntitiesIterator() );
session.getInterceptor()
.postFlush( session.getPersistenceContextInternal().managedEntitiesIterator() );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.hibernate.jpa.event.spi.CallbackRegistry;
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.generator.Generator;
import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.type.Type;
import org.hibernate.type.TypeHelper;
Expand Down Expand Up @@ -74,7 +73,7 @@ protected Object saveWithRequestedId(
String entityName,
C context,
EventSource source) {
final EntityPersister persister = source.getEntityPersister( entityName, entity );
final var persister = source.getEntityPersister( entityName, entity );
return performSave( entity, requestedId, persister, false, context, source, false );
}

Expand Down Expand Up @@ -199,9 +198,9 @@ protected Object performSave(
callbackRegistry.preCreate( entity );

processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
processIfManagedEntity( entity, (managedEntity) -> managedEntity.$$_hibernate_setUseTracker( true ) );
processIfManagedEntity( entity, managedEntity -> managedEntity.$$_hibernate_setUseTracker( true ) );

final Generator generator = persister.getGenerator();
final var generator = persister.getGenerator();
if ( !generator.generatesOnInsert() || generator instanceof CompositeNestedGeneratedValueGenerator ) {
id = persister.getIdentifier( entity, source );
if ( id == null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.hibernate.type.Type;
import org.hibernate.type.TypeHelper;

import static java.util.Arrays.fill;
import static org.hibernate.engine.internal.Collections.skipRemoval;
import static org.hibernate.pretty.MessageHelper.infoString;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
Expand Down Expand Up @@ -372,7 +373,6 @@ protected final void deleteEntity(
LOG.trace( "Deleting " + infoString( persister, entityEntry.getId(), session.getFactory() ) );
}

final var persistenceContext = session.getPersistenceContextInternal();
final Object version = entityEntry.getVersion();

final Object[] currentState =
Expand All @@ -391,6 +391,8 @@ protected final void deleteEntity(
persister.getPropertyTypes()
);

final var persistenceContext = session.getPersistenceContextInternal();

// before any callbacks, etc., so subdeletions see that this deletion happened first
persistenceContext.setEntryStatus( entityEntry, Status.DELETED );
final var key = session.generateEntityKey( entityEntry.getId(), persister );
Expand Down Expand Up @@ -452,7 +454,7 @@ private Object[] createDeletedState(
final Object[] deletedState = new Object[types.length];
if ( !persister.hasCollections() || !persister.hasUninitializedLazyProperties( parent ) ) {
final boolean[] copyability = new boolean[types.length];
java.util.Arrays.fill( copyability, true );
fill( copyability, true );
TypeHelper.deepCopy( currentState, types, copyability, deletedState, eventSource );
return deletedState;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ public void checkId(Object object, EntityPersister persister, EntityEntry entry,
}
if ( !(entryId instanceof DelayedPostInsertIdentifier) ) {
final Object currentId = persister.getIdentifier( object, session );
// Small optimisation: always try to avoid getIdentifierType().isEqual(..) when possible.
// (However it's not safe to invoke the equals() method as it might trigger side effects.)
// Small optimization: always try to avoid getIdentifierType().isEqual(..) when possible.
// (However, it's not safe to invoke the equals() method as it might trigger side effects.)
if ( entryId != currentId
&& !entry.getStatus().isDeletedOrGone()
&& !persister.getIdentifierType().isEqual( entryId, currentId, session.getFactory() ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ public void onFlush(FlushEvent event) throws HibernateException {
if ( persistenceContext.getNumberOfManagedEntities() > 0
|| persistenceContext.getCollectionEntriesSize() > 0 ) {
final var flushEvent = eventMonitor.beginFlushEvent();
final var eventListenerManager = source.getEventListenerManager();
try {
source.getEventListenerManager().flushStart();

eventListenerManager.flushStart();
flushEverythingToExecutions( event );
performExecutions( source );
postFlush( source );
}
finally {
eventMonitor.completeFlushEvent( flushEvent, event );
source.getEventListenerManager().flushEnd(
eventListenerManager.flushEnd(
event.getNumberOfEntitiesProcessed(),
event.getNumberOfCollectionsProcessed()
);
Expand Down
Loading
Loading