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 @@ -12,19 +12,13 @@
import org.hibernate.engine.internal.Nullability.NullabilityCheckType;
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityHolder;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.NaturalIdResolutions;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.spi.EventSource;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMappingsList;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.EntityPersister;

Expand Down Expand Up @@ -133,33 +127,33 @@ protected final void nullifyTransientReferencesIfNotAlready() {
*/
public final void makeEntityManaged() {
nullifyTransientReferencesIfNotAlready();
final Object version = getVersion( getState(), getPersister() );
final PersistenceContext persistenceContextInternal = getSession().getPersistenceContextInternal();
final EntityHolder entityHolder = persistenceContextInternal.addEntityHolder(
getEntityKey(),
getInstance()
);
final EntityEntry entityEntry = persistenceContextInternal.addEntry(
final var persister = getPersister();
final var key = getEntityKey();
final Object[] state = getState();
final Object version = getVersion( state, persister );
final var persistenceContext = getSession().getPersistenceContextInternal();
final var entityHolder = persistenceContext.addEntityHolder( key, getInstance() );
final var entityEntry = persistenceContext.addEntry(
getInstance(),
getPersister().isMutable() ? Status.MANAGED : Status.READ_ONLY,
getState(),
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
state,
getRowId(),
getEntityKey().getIdentifier(),
key.getIdentifier(),
version,
LockMode.WRITE,
isExecuted,
getPersister(),
persister,
isVersionIncrementDisabled
);
entityHolder.setEntityEntry( entityEntry );
if ( isEarlyInsert() ) {
addCollectionsByKeyToPersistenceContext( persistenceContextInternal, getState() );
addCollectionsByKeyToPersistenceContext( persistenceContext, state );
}
}

protected void addCollectionsByKeyToPersistenceContext(PersistenceContext persistenceContext, Object[] objects) {
for ( int i = 0; i < objects.length; i++ ) {
final AttributeMapping attributeMapping = getPersister().getAttributeMapping( i );
final var attributeMapping = getPersister().getAttributeMapping( i );
if ( attributeMapping.isEmbeddedAttributeMapping() ) {
visitEmbeddedAttributeMapping(
attributeMapping.asEmbeddedAttributeMapping(),
Expand All @@ -182,13 +176,12 @@ private void visitEmbeddedAttributeMapping(
Object object,
PersistenceContext persistenceContext) {
if ( object != null ) {
final EmbeddableMappingType descriptor = attributeMapping.getEmbeddableTypeDescriptor();
final EmbeddableMappingType.ConcreteEmbeddableType concreteEmbeddableType = descriptor.findSubtypeBySubclass(
object.getClass().getName()
);
final AttributeMappingsList attributeMappings = descriptor.getAttributeMappings();
final var descriptor = attributeMapping.getEmbeddableTypeDescriptor();
final var concreteEmbeddableType =
descriptor.findSubtypeBySubclass( object.getClass().getName() );
final var attributeMappings = descriptor.getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attribute = attributeMappings.get( i );
final var attribute = attributeMappings.get( i );
if ( concreteEmbeddableType.declaresAttribute( attribute ) ) {
if ( attribute.isPluralAttributeMapping() ) {
addCollectionKey(
Expand All @@ -214,15 +207,15 @@ private void addCollectionKey(
Object object,
PersistenceContext persistenceContext) {
if ( object instanceof PersistentCollection ) {
final CollectionPersister collectionPersister = pluralAttributeMapping.getCollectionDescriptor();
final var collectionPersister = pluralAttributeMapping.getCollectionDescriptor();
final Object key = AbstractEntityPersister.getCollectionKey(
collectionPersister,
getInstance(),
persistenceContext.getEntry( getInstance() ),
getSession()
);
if ( key != null ) {
final CollectionKey collectionKey = new CollectionKey( collectionPersister, key );
final var collectionKey = new CollectionKey( collectionPersister, key );
persistenceContext.addCollectionByKey( collectionKey, (PersistentCollection<?>) object );
}
}
Expand All @@ -243,13 +236,17 @@ protected void markExecuted() {

protected abstract Object getRowId();

private NaturalIdResolutions getNaturalIdResolutions() {
return getSession().getPersistenceContextInternal().getNaturalIdResolutions();
}

@Override
public void afterDeserialize(EventSource session) {
super.afterDeserialize( session );
// IMPL NOTE: non-flushed changes code calls this method with session == null...
// guard against NullPointerException
if ( session != null ) {
final EntityEntry entityEntry = session.getPersistenceContextInternal().getEntry( getInstance() );
final var entityEntry = session.getPersistenceContextInternal().getEntry( getInstance() );
this.state = entityEntry.getLoadedState();
}
}
Expand All @@ -259,9 +256,9 @@ public void afterDeserialize(EventSource session) {
*/
protected void handleNaturalIdPreSaveNotifications() {
// before save, we need to add a natural id cross-reference to the persistence-context
final NaturalIdMapping naturalIdMapping = getPersister().getNaturalIdMapping();
final var naturalIdMapping = getPersister().getNaturalIdMapping();
if ( naturalIdMapping != null ) {
getSession().getPersistenceContextInternal().getNaturalIdResolutions().manageLocalResolution(
getNaturalIdResolutions().manageLocalResolution(
getId(),
naturalIdMapping.extractNaturalIdFromEntityState( state ),
getPersister(),
Expand All @@ -276,24 +273,26 @@ protected void handleNaturalIdPreSaveNotifications() {
* @param generatedId The generated entity identifier
*/
public void handleNaturalIdPostSaveNotifications(Object generatedId) {
final NaturalIdMapping naturalIdMapping = getPersister().getNaturalIdMapping();
final var persister = getPersister();
final var naturalIdMapping = persister.getNaturalIdMapping();
if ( naturalIdMapping != null ) {
final Object naturalIdValues = naturalIdMapping.extractNaturalIdFromEntityState( state );
final var resolutions = getNaturalIdResolutions();
if ( isEarlyInsert() ) {
// with early insert, we still need to add a local (transactional) natural id cross-reference
getSession().getPersistenceContextInternal().getNaturalIdResolutions().manageLocalResolution(
resolutions.manageLocalResolution(
generatedId,
naturalIdValues,
getPersister(),
persister,
CachedNaturalIdValueSource.INSERT
);
}
// after save, we need to manage the shared cache entries
getSession().getPersistenceContextInternal().getNaturalIdResolutions().manageSharedResolution(
resolutions.manageSharedResolution(
generatedId,
naturalIdValues,
null,
getPersister(),
persister,
CachedNaturalIdValueSource.INSERT
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
Expand All @@ -22,14 +21,13 @@
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.spi.EventSource;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.tree.SqmDmlStatement;
import org.hibernate.query.sqm.tree.SqmQuery;
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
import org.hibernate.sql.ast.tree.insert.InsertSelectStatement;

import static java.util.Collections.addAll;
import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY;

/**
* An {@link org.hibernate.engine.spi.ActionQueue} {@link Executable} for
* ensuring shared cache cleanup in relation to performed bulk HQL queries.
Expand Down Expand Up @@ -62,27 +60,25 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
*/
public BulkOperationCleanupAction(SharedSessionContractImplementor session, EntityPersister... affectedQueryables) {
final LinkedHashSet<String> spacesList = new LinkedHashSet<>();
for ( EntityPersister persister : affectedQueryables ) {
Collections.addAll( spacesList, (String[]) persister.getQuerySpaces() );
for ( var persister : affectedQueryables ) {
addAll( spacesList, (String[]) persister.getQuerySpaces() );

if ( persister.canWriteToCache() ) {
final EntityDataAccess entityDataAccess = persister.getCacheAccessStrategy();
final var entityDataAccess = persister.getCacheAccessStrategy();
if ( entityDataAccess != null ) {
entityCleanups.add( new EntityCleanup( entityDataAccess, session ) );
}
}

if ( persister.hasNaturalIdentifier() && persister.hasNaturalIdCache() ) {
naturalIdCleanups.add(
new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session )
);
naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session ) );
}

final MappingMetamodelImplementor mappingMetamodel = session.getFactory().getMappingMetamodel();
final Set<String> roles = mappingMetamodel.getCollectionRolesByEntityParticipant( persister.getEntityName() );
final var mappingMetamodel = session.getFactory().getMappingMetamodel();
final var roles = mappingMetamodel.getCollectionRolesByEntityParticipant( persister.getEntityName() );
if ( roles != null ) {
for ( String role : roles ) {
final CollectionPersister collectionPersister = mappingMetamodel.getCollectionDescriptor( role );
final var collectionPersister = mappingMetamodel.getCollectionDescriptor( role );
if ( collectionPersister.hasCache() ) {
collectionCleanups.add(
new CollectionCleanup( collectionPersister.getCacheAccessStrategy(), session )
Expand All @@ -92,7 +88,7 @@ public BulkOperationCleanupAction(SharedSessionContractImplementor session, Enti
}
}

this.affectedTableSpaces = spacesList.toArray( new String[ 0 ] );
affectedTableSpaces = spacesList.toArray( EMPTY_STRING_ARRAY );
}

/**
Expand All @@ -111,11 +107,11 @@ public BulkOperationCleanupAction(SharedSessionContractImplementor session, Enti
public BulkOperationCleanupAction(SharedSessionContractImplementor session, Set<String> tableSpaces) {
final LinkedHashSet<String> spacesList = new LinkedHashSet<>( tableSpaces );

final MappingMetamodelImplementor metamodel = session.getFactory().getMappingMetamodel();
metamodel.forEachEntityDescriptor( (entityDescriptor) -> {
final var metamodel = session.getFactory().getMappingMetamodel();
metamodel.forEachEntityDescriptor( entityDescriptor -> {
final String[] entitySpaces = (String[]) entityDescriptor.getQuerySpaces();
if ( affectedEntity( tableSpaces, entitySpaces ) ) {
Collections.addAll( spacesList, entitySpaces );
addAll( spacesList, entitySpaces );

if ( entityDescriptor.canWriteToCache() ) {
entityCleanups.add( new EntityCleanup( entityDescriptor.getCacheAccessStrategy(), session ) );
Expand All @@ -124,10 +120,10 @@ public BulkOperationCleanupAction(SharedSessionContractImplementor session, Set<
naturalIdCleanups.add( new NaturalIdCleanup( entityDescriptor.getNaturalIdCacheAccessStrategy(), session ) );
}

final Set<String> roles = metamodel.getCollectionRolesByEntityParticipant( entityDescriptor.getEntityName() );
final var roles = metamodel.getCollectionRolesByEntityParticipant( entityDescriptor.getEntityName() );
if ( roles != null ) {
for ( String role : roles ) {
final CollectionPersister collectionDescriptor = metamodel.getCollectionDescriptor( role );
final var collectionDescriptor = metamodel.getCollectionDescriptor( role );
if ( collectionDescriptor.hasCache() ) {
collectionCleanups.add(
new CollectionCleanup( collectionDescriptor.getCacheAccessStrategy(), session )
Expand All @@ -138,29 +134,26 @@ public BulkOperationCleanupAction(SharedSessionContractImplementor session, Set<
}
} );

this.affectedTableSpaces = spacesList.toArray( new String[ 0 ] );
affectedTableSpaces = spacesList.toArray( EMPTY_STRING_ARRAY );
}

public static void schedule(SharedSessionContractImplementor session, SqmDmlStatement<?> statement) {
final List<EntityPersister> entityPersisters = new ArrayList<>( 1 );
final MappingMetamodelImplementor metamodel = session.getFactory().getMappingMetamodel();
final var metamodel = session.getFactory().getMappingMetamodel();
if ( !( statement instanceof InsertSelectStatement ) ) {
entityPersisters.add( metamodel.getEntityDescriptor( statement.getTarget().getEntityName() ) );
}
for ( SqmCteStatement<?> cteStatement : statement.getCteStatements() ) {
final SqmQuery<?> cteDefinition = cteStatement.getCteDefinition();
if ( cteDefinition instanceof SqmDmlStatement<?> dmlStatement ) {
entityPersisters.add(
metamodel.getEntityDescriptor( dmlStatement.getTarget().getEntityName() )
);
for ( var cteStatement : statement.getCteStatements() ) {
if ( cteStatement.getCteDefinition() instanceof SqmDmlStatement<?> dmlStatement ) {
entityPersisters.add( metamodel.getEntityDescriptor( dmlStatement.getTarget().getEntityName() ) );
}
}

schedule( session, entityPersisters.toArray( new EntityPersister[0] ) );
}

public static void schedule(SharedSessionContractImplementor session, EntityPersister... affectedQueryables) {
final BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, affectedQueryables );
final var action = new BulkOperationCleanupAction( session, affectedQueryables );
if ( session.isEventSource() ) {
session.asEventSource().getActionQueue().addAction( action );
}
Expand All @@ -170,7 +163,7 @@ public static void schedule(SharedSessionContractImplementor session, EntityPers
}

public static void schedule(SharedSessionContractImplementor session, Set<String> affectedQueryables) {
final BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, affectedQueryables );
final var action = new BulkOperationCleanupAction( session, affectedQueryables );
if ( session.isEventSource() ) {
session.asEventSource().getActionQueue().addAction( action );
}
Expand Down Expand Up @@ -199,13 +192,14 @@ private boolean affectedEntity(Set<?> affectedTableSpaces, Serializable[] checkT
if ( affectedTableSpaces == null || affectedTableSpaces.isEmpty() ) {
return true;
}

for ( Serializable checkTableSpace : checkTableSpaces ) {
if ( affectedTableSpaces.contains( checkTableSpace ) ) {
return true;
else {
for ( Serializable checkTableSpace : checkTableSpaces ) {
if ( affectedTableSpaces.contains( checkTableSpace ) ) {
return true;
}
}
return false;
}
return false;
}

@Override
Expand All @@ -221,17 +215,17 @@ public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess(
@Override
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() {
return (success, session) -> {
for ( EntityCleanup cleanup : entityCleanups ) {
for ( var cleanup : entityCleanups ) {
cleanup.release();
}
entityCleanups.clear();

for ( NaturalIdCleanup cleanup : naturalIdCleanups ) {
for ( var cleanup : naturalIdCleanups ) {
cleanup.release();
}
naturalIdCleanups.clear();

for ( CollectionCleanup cleanup : collectionCleanups ) {
for ( var cleanup : collectionCleanups ) {
cleanup.release();
}
collectionCleanups.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ protected final EventSource getSession() {

protected final void evict() throws CacheException {
if ( persister.hasCache() ) {
final CollectionDataAccess cache = persister.getCacheAccessStrategy();
final var cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(
key,
persister,
Expand Down
Loading