HHH-16602 Dedicated action queue priority for orphan collection removals

This commit is contained in:
Marco Belladelli 2023-06-19 16:13:19 +02:00
parent 4d72a10cba
commit 02e2172778
2 changed files with 34 additions and 4 deletions

View File

@ -154,4 +154,7 @@ public final class CollectionRemoveAction extends CollectionAction {
); );
} }
public Object getAffectedOwner() {
return affectedOwner;
}
} }

View File

@ -94,6 +94,7 @@ public class ActionQueue {
private ExecutableList<CollectionUpdateAction> collectionUpdates; private ExecutableList<CollectionUpdateAction> collectionUpdates;
private ExecutableList<QueuedOperationCollectionAction> collectionQueuedOps; private ExecutableList<QueuedOperationCollectionAction> collectionQueuedOps;
private ExecutableList<CollectionRemoveAction> collectionRemovals; private ExecutableList<CollectionRemoveAction> collectionRemovals;
private ExecutableList<CollectionRemoveAction> orphanCollectionRemovals;
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task // TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task
// ordering is improved. // ordering is improved.
@ -110,15 +111,15 @@ public class ActionQueue {
//The order of these operations is very important //The order of these operations is very important
private enum OrderedActions { private enum OrderedActions {
CollectionRemoveAction { OrphanCollectionRemoveAction {
@Override @Override
public ExecutableList<?> getActions(ActionQueue instance) { public ExecutableList<?> getActions(ActionQueue instance) {
return instance.collectionRemovals; return instance.orphanCollectionRemovals;
} }
@Override @Override
public void ensureInitialized(ActionQueue instance) { public void ensureInitialized(ActionQueue instance) {
if ( instance.collectionRemovals == null ) { if ( instance.orphanCollectionRemovals == null ) {
instance.collectionRemovals = new ExecutableList<>( instance.isOrderUpdatesEnabled() ); instance.orphanCollectionRemovals = new ExecutableList<>( instance.isOrderUpdatesEnabled() );
} }
} }
}, },
@ -173,6 +174,18 @@ public class ActionQueue {
} }
} }
}, },
CollectionRemoveAction {
@Override
public ExecutableList<?> getActions(ActionQueue instance) {
return instance.collectionRemovals;
}
@Override
public void ensureInitialized(ActionQueue instance) {
if ( instance.collectionRemovals == null ) {
instance.collectionRemovals = new ExecutableList<>( instance.isOrderUpdatesEnabled() );
}
}
},
CollectionUpdateAction { CollectionUpdateAction {
@Override @Override
public ExecutableList<?> getActions(ActionQueue instance) { public ExecutableList<?> getActions(ActionQueue instance) {
@ -355,6 +368,20 @@ public class ActionQueue {
* @param action The action representing the removal of a collection * @param action The action representing the removal of a collection
*/ */
public void addAction(final CollectionRemoveAction action) { public void addAction(final CollectionRemoveAction action) {
if ( orphanRemovals != null && action.getAffectedOwner() != null && session.getPersistenceContextInternal()
.getEntry( action.getAffectedOwner() )
.getStatus()
.isDeletedOrGone() ) {
// We need to check if this collection's owner is an orphan being removed,
// which case we should remove the collection first to avoid constraint violations
for ( OrphanRemovalAction orphanRemoval : orphanRemovals ) {
if ( orphanRemoval.getInstance() == action.getAffectedOwner() ) {
OrderedActions.OrphanCollectionRemoveAction.ensureInitialized( this );
this.orphanCollectionRemovals.add( action );
return;
}
}
}
OrderedActions.CollectionRemoveAction.ensureInitialized( this ); OrderedActions.CollectionRemoveAction.ensureInitialized( this );
this.collectionRemovals.add( action ); this.collectionRemovals.add( action );
} }