hibernate/hibernate-orm · error · IllegalStateException

There are delayed insert actions before operation as cascade

Error message

There are delayed insert actions before operation as cascade level 0.

What it means

With identity-style immediate inserts (IDENTITY generation, or inserts queued via ActionQueue), Hibernate can end a unit of work with 'unresolved entity insert actions' — inserts held back because they participate in circular FK dependencies. Operations such as lock() call checkNoUnresolvedActionsBeforeOperation(), which refuses to run while such actions are pending at cascade level 0, throwing IllegalStateException. This guards against executing an operation whose outcome could depend on un-flushed insert state.

Source

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

		// todo : should this get moved to PersistentContext?
		// logically, is PersistentContext the "thing" to which an interceptor gets attached?
		final Object result = persistenceContext.getEntity( key );
		if ( result == null ) {
			final Object newObject = callInterceptorCallback(
					() -> getInterceptor().getEntity( key.getEntityName(), key.getIdentifier() ) );
			if ( newObject != null ) {
				lock( newObject, LockMode.NONE );
			}
			return newObject;
		}
		else {
			return result;
		}
	}

	protected void checkNoUnresolvedActionsBeforeOperation() {
		if ( persistenceContext.getCascadeLevel() == 0 && actionQueue.hasUnresolvedEntityInsertActions() ) {
			throw new IllegalStateException( "There are delayed insert actions before operation as cascade level 0." );
		}
	}

	protected void checkNoUnresolvedActionsAfterOperation() {
		if ( persistenceContext.getCascadeLevel() == 0 ) {
			actionQueue.checkNoUnresolvedActionsAfterOperation();
		}
		delayedAfterCompletion();
	}

	@Override
	public void delayedAfterCompletion() {
		super.delayedAfterCompletion();
	}

	@Override
	public void pulseTransactionCoordinator() {
		super.pulseTransactionCoordinator();

View on GitHub (pinned to fad1729dce)

Solutions

  1. Flush first: session.flush() resolves the pending insert actions before the guarded operation
  2. Switch identifier generation to SEQUENCE (or pooled/table) so inserts are not forced through the unresolved-action queue
  3. Break the FK cycle: make one side nullable and set the association after both saves, or use join-table mapping
  4. Reorder the code so lock/refresh happens before persisting the circular graph

Example fix

// before (Order.id is IDENTITY, Order.customer <-> Customer.orders circular FK)
session.persist(order);
session.lock(customer, LockMode.NONE); // IllegalStateException: delayed insert actions

// after
session.persist(order);
session.flush();            // resolve delayed insert actions first
session.lock(customer, LockMode.NONE);
Defensive patterns

Strategy: try-catch

Validate before calling

// Flush resolves pending identity inserts before guarded operations
if (!session.getActionQueue().hasUnresolvedEntityInsertActions()) {
    session.lock(entity, LockMode.NONE);
} else {
    session.flush();
    session.lock(entity, LockMode.NONE);
}

Try / catch

try {
    session.lock(entity, LockMode.NONE);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("delayed insert actions")) {
        session.flush();                       // resolve the delayed inserts
        session.lock(entity, LockMode.NONE);   // retry once
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Persisting entities with IDENTITY identifiers involved in bidirectional FK cycles, then calling session.lock/refresh/get-style guarded operations before a flush resolves the queue. Triggered when persistenceContext.getCascadeLevel() == 0 and actionQueue.hasUnresolvedEntityInsertActions().

Common situations: Parent/child mutual references with IDENTITY keys on MySQL/SQL Server (no sequences); circular foreign keys between two new entities; legacy schemas forcing IDENTITY; operations triggered lazily (lazy loading forcing the check) right after saving such a graph.

Related errors


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