hibernate/hibernate-orm · error · ObjectDeletedException

deleted object would be re-saved by cascade (remove deleted

Error message

deleted object would be re-saved by cascade (remove deleted object from associations)

What it means

When Hibernate must force a flush to push a deletion through (e.g. a subsequent operation needs the row gone), it calls forceFlush(EntityKey). If the session is currently mid-cascade, flushing would re-execute cascades and re-save the just-deleted entity, so Hibernate throws ObjectDeletedException('deleted object would be re-saved by cascade...'). The message names the classic cause: the deleted object is still referenced from an association that cascade-saves it.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java:1552

	@Nonnull
	public Set<EntityManager.Option> getOptions() {
		return OptionsHelper.getOptions( this );
	}

	@Override
	public void forceFlush(@Nonnull EntityEntry entityEntry) {
		forceFlush( entityEntry.getEntityKey() );
	}

	@Override
	public void forceFlush(@Nonnull EntityKey key) {
		if ( SESSION_LOGGER.isTraceEnabled() ) {
			SESSION_LOGGER.flushingToForceDeletion(
					infoString( key.getPersister(), key.getIdentifier(), getFactory() ) );
		}

		if ( persistenceContext.getCascadeLevel() > 0 ) {
			throw new ObjectDeletedException(
					"deleted object would be re-saved by cascade (remove deleted object from associations)",
					key.getIdentifier(),
					key.getPersister().getEntityName()
			);
		}
		checkOpenOrWaitingForAutoClose();
		fireFlush();
	}

	/**
	 * give the interceptor an opportunity to override the default instantiation
	 */
	@Override
	@Nonnull
	public Object instantiate(@Nonnull EntityPersister persister, @Nullable Object id) {
		checkOpenOrWaitingForAutoClose();
		pulseTransactionCoordinator();
		Object result = callInterceptorCallback(

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove the entity from all owning associations before delete: parent.getChildren().remove(child); session.remove(child);
  2. Use orphanRemoval=true on the collection so removal from the collection implies deletion, avoiding manual remove of a still-referenced entity
  3. Check/adjust cascade settings: cascade=REMOVE or orphanRemoval instead of blanket cascade=ALL when children are managed through one side only
  4. Flush immediately after the delete (session.flush()) so later cascade work does not hit the pending deletion

Example fix

// before
order.getItems().size(); // cascade=ALL on items
session.remove(item);          // still inside order.items
session.remove(order);         // forceFlush during cascade -> ObjectDeletedException

// after
order.getItems().remove(item); // sever association first
session.remove(item);
session.flush();               // deletion is now safely applied
session.remove(order);
Defensive patterns

Strategy: try-catch

Validate before calling

// Sever associations before deleting, so cascade cannot re-save the entity
parent.getChildren().remove(child);
session.remove(child);
session.flush(); // apply deletion before further cascade work

Try / catch

try {
    session.remove(entity);
    session.flush();
} catch (ObjectDeletedException e) {
    // entity is still referenced by a cascade-persisting association
    throw new IllegalStateException(
        "Remove '" + e.getEntityName() + "' from its parent collection before deleting", e);
}

Prevention

When it happens

Trigger: session.remove(x) while x is still held in a cascade-persisting collection (e.g. parent.getChildren() still contains x with cascade=ALL), then any operation (delete of the parent, lock, query with auto-flush) triggers forceFlush while cascadeLevel > 0. Also bidirectional relations where the many-to-one side still points at the removed entity.

Common situations: Forgetting parent.getChildren().remove(child) before removing child; orphanRemoval=false with cascade=ALL; deleting a child then re-saving the parent in the same transaction; bulk re-save loops that walk collections containing soft-deleted items.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/fa2f0337082b9639. Report an issue: GitHub.