use of org.hibernate.reactive.engine.ReactiveActionQueue in project hibernate-reactive by hibernate.
the class DefaultReactiveDeleteEventListener method deleteEntity.
/**
* Perform the entity deletion. Well, as with most operations, does not
* really perform it; just schedules an action/execution with the
* {@link org.hibernate.engine.spi.ActionQueue} for execution during flush.
*
* @param session The originating session
* @param entity The entity to delete
* @param entityEntry The entity's entry in the {@link PersistenceContext}
* @param isCascadeDeleteEnabled Is delete cascading enabled?
* @param persister The entity persister.
* @param transientEntities A cache of already deleted entities.
*/
protected CompletionStage<Void> deleteEntity(final EventSource session, final Object entity, final EntityEntry entityEntry, final boolean isCascadeDeleteEnabled, final boolean isOrphanRemovalBeforeUpdates, final EntityPersister persister, final IdentitySet transientEntities) {
if (LOG.isTraceEnabled()) {
LOG.tracev("Deleting {0}", infoString(persister, entityEntry.getId(), session.getFactory()));
}
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final Type[] propTypes = persister.getPropertyTypes();
final Object version = entityEntry.getVersion();
final Object[] currentState;
if (entityEntry.getLoadedState() == null) {
// ie. the entity came in from update()
currentState = persister.getPropertyValues(entity);
} else {
currentState = entityEntry.getLoadedState();
}
final Object[] deletedState = createDeletedState(persister, currentState, session);
entityEntry.setDeletedState(deletedState);
session.getInterceptor().onDelete(entity, entityEntry.getId(), deletedState, persister.getPropertyNames(), propTypes);
// before any callbacks, etc, so subdeletions see that this deletion happened first
persistenceContext.setEntryStatus(entityEntry, Status.DELETED);
final EntityKey key = session.generateEntityKey(entityEntry.getId(), persister);
CompletionStage<Void> beforeDelete = cascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities);
CompletionStage<Void> nullifyAndAction = new ForeignKeys.Nullifier(entity, true, false, session, persister).nullifyTransientReferences(entityEntry.getDeletedState()).thenAccept(v -> {
new Nullability(session).checkNullability(entityEntry.getDeletedState(), persister, Nullability.NullabilityCheckType.DELETE);
persistenceContext.registerNullifiableEntityKey(key);
ReactiveActionQueue actionQueue = actionQueue(session);
if (isOrphanRemovalBeforeUpdates) {
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task
// ordering is improved.
actionQueue.addAction(new ReactiveOrphanRemovalAction(entityEntry.getId(), deletedState, version, entity, persister, isCascadeDeleteEnabled, session));
} else {
// Ensures that containing deletions happen before sub-deletions
actionQueue.addAction(new ReactiveEntityDeleteAction(entityEntry.getId(), deletedState, version, entity, persister, isCascadeDeleteEnabled, session));
}
});
CompletionStage<Void> afterDelete = cascadeAfterDelete(session, persister, entity, transientEntities);
return beforeDelete.thenCompose(v -> nullifyAndAction).thenCompose(v -> afterDelete);
}
use of org.hibernate.reactive.engine.ReactiveActionQueue in project hibernate-reactive by hibernate.
the class AbstractReactiveFlushingEventListener method flushCollections.
/**
* process any unreferenced collections and then inspect all known collections,
* scheduling creates/removes/updates
*/
private int flushCollections(final EventSource session, final PersistenceContext persistenceContext) throws HibernateException {
LOG.trace("Processing unreferenced collections");
final int count = persistenceContext.getCollectionEntriesSize();
persistenceContext.forEachCollectionEntry((persistentCollection, collectionEntry) -> {
if (!collectionEntry.isReached() && !collectionEntry.isIgnore()) {
Collections.processUnreachableCollection(persistentCollection, session);
}
}, true);
// Schedule updates to collections:
LOG.trace("Scheduling collection removes/(re)creates/updates");
final ReactiveActionQueue actionQueue = session.unwrap(ReactiveSession.class).getReactiveActionQueue();
final Interceptor interceptor = session.getInterceptor();
persistenceContext.forEachCollectionEntry((coll, ce) -> {
if (ce.isDorecreate()) {
interceptor.onCollectionRecreate(coll, ce.getCurrentKey());
actionQueue.addAction(new ReactiveCollectionRecreateAction(coll, ce.getCurrentPersister(), ce.getCurrentKey(), session));
}
if (ce.isDoremove()) {
interceptor.onCollectionRemove(coll, ce.getLoadedKey());
actionQueue.addAction(new ReactiveCollectionRemoveAction(coll, ce.getLoadedPersister(), ce.getLoadedKey(), ce.isSnapshotEmpty(coll), session));
}
if (ce.isDoupdate()) {
interceptor.onCollectionUpdate(coll, ce.getLoadedKey());
actionQueue.addAction(new ReactiveCollectionUpdateAction(coll, ce.getLoadedPersister(), ce.getLoadedKey(), ce.isSnapshotEmpty(coll), session));
}
// todo : I'm not sure the !wasInitialized part should really be part of this check
if (!coll.wasInitialized() && coll.hasQueuedOperations()) {
actionQueue.addAction(new QueuedOperationCollectionAction(coll, ce.getLoadedPersister(), ce.getLoadedKey(), session));
}
}, true);
actionQueue.sortCollectionActions();
return count;
}
Aggregations