HHH-15651 StatefulPersistenceContext#clear shouldn't need defensive copies for iteration

This commit is contained in:
Sanne Grinovero 2022-11-01 16:51:21 +00:00 committed by Sanne Grinovero
parent 001de2b203
commit cdbf92fd71
2 changed files with 19 additions and 4 deletions

View File

@ -22,6 +22,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.Consumer;
import static org.hibernate.engine.internal.ManagedTypeHelper.asManagedEntity;
import static org.hibernate.engine.internal.ManagedTypeHelper.isManaged;
@ -329,6 +330,18 @@ public class EntityEntryContext {
return reentrantSafeEntries;
}
/**
* Not reentrant like #reentrantSafeEntityEntries but most likely
* the more efficient choice, when reentrant safety isn't required.
*/
public void processEachEntity(final Consumer<Object> entityProcessor) {
ManagedEntity managedEntity = head;
while ( managedEntity != null ) {
entityProcessor.accept( managedEntity.$$_hibernate_getEntityInstance() );
managedEntity = managedEntity.$$_hibernate_getNextManagedEntity();
}
}
/**
* Clear this context of all managed entities
*/

View File

@ -232,10 +232,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
} );
}
for ( Entry<Object, EntityEntry> objectEntityEntryEntry : entityEntryContext.reentrantSafeEntityEntries() ) {//TODO make this a forEach process within the container
//type-cache-pollution agent: always check for EnhancedEntity type first.
ManagedTypeHelper.processIfPersistentAttributeInterceptable( objectEntityEntryEntry.getKey(), StatefulPersistenceContext::unsetSession, null );
}
entityEntryContext.processEachEntity( StatefulPersistenceContext::processEntityOnClear );
final SharedSessionContractImplementor session = getSession();
if ( collectionEntries != null ) {
@ -266,6 +263,11 @@ public class StatefulPersistenceContext implements PersistenceContext {
naturalIdResolutions = null;
}
private static void processEntityOnClear(final Object entity) {
//type-cache-pollution agent: always check for EnhancedEntity type first.
ManagedTypeHelper.processIfPersistentAttributeInterceptable( entity, StatefulPersistenceContext::unsetSession, null );
}
private static void unsetSession(PersistentAttributeInterceptable persistentAttributeInterceptable, Object ignoredParam) {
final PersistentAttributeInterceptor interceptor = persistentAttributeInterceptable.$$_hibernate_getInterceptor();
if ( interceptor instanceof LazyAttributeLoadingInterceptor ) {