hibernate/hibernate-orm · error · UnsupportedOperationException

queued clear cannot be used with orphan delete

Error message

queued clear cannot be used with orphan delete

What it means

PersistentMap queues operations on an uninitialized lazy Map, so clear() on an uninitialized map becomes a queued Clear operation. A bulk Clear cannot enumerate which entries were removed, so when the association has orphan delete enabled (orphanRemoval=true / delete-orphan) and flush asks the queued operation for its orphan, getOrphan() throws UnsupportedOperationException. Map flavor of the same limitation as PersistentList.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentMap.java:613

	@Override
	public boolean entryExists(Object entry, int i) {
		return ( (Entry<?,?>) entry ).getValue() != null;
	}

	final class Clear implements DelayedOperation<E> {
		@Override
		public void operate() {
			map.clear();
		}

		@Override
		public E getAddedInstance() {
			return null;
		}

		@Override
		public E getOrphan() {
			throw new UnsupportedOperationException( "queued clear cannot be used with orphan delete" );
		}
	}

	abstract class AbstractMapValueDelayedOperation extends AbstractValueDelayedOperation {
		private final K index;

		protected AbstractMapValueDelayedOperation(K index, E addedValue, E orphan) {
			super( addedValue, orphan );
			this.index = index;
		}

		protected final K getIndex() {
			return index;
		}

		@Override
		public Object getAddedEntry() {
			return Map.entry( getIndex(), getAddedInstance() );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Initialize the map before clearing: Hibernate.initialize(parent.getChildren()) or call size() first
  2. Remove entries individually on the initialized map so each Remove carries its orphan
  3. Drop orphanRemoval for map associations managed by clear-and-replace
  4. Cover the update flow with a flush-performing test against the real mapping

Example fix

// before
parent.getChildren().clear(); // uninitialized PersistentMap -> queued Clear
parent.getChildren().putAll(newEntries);
tx.commit();

// after
Hibernate.initialize(parent.getChildren());
parent.getChildren().clear();
parent.getChildren().putAll(newEntries);
Defensive patterns

Strategy: validation

Validate before calling

Map<String, Item> children = parent.getChildren();
if (children instanceof org.hibernate.collection.spi.PersistentCollection pc && !pc.wasInitialized()) {
    org.hibernate.Hibernate.initialize(children);
}
children.clear();

Try / catch

try {
    tx.commit();
} catch (org.hibernate.HibernateException e) {
    Throwable c = e;
    while (c != null) {
        if (c instanceof UnsupportedOperationException && String.valueOf(c.getMessage()).contains("queued clear")) {
            throw new IllegalStateException("clear() on uninitialized map with orphanRemoval; initialize first", e);
        }
        c = c.getCause();
    }
    throw e;
}

Prevention

When it happens

Trigger: @OneToMany(orphanRemoval = true) @MapKeyColumn Map<String, Item> children; parent loaded without touching the map; children.clear() called; flush requires orphan deletion for the collection role.

Common situations: Keyed child collections replaced wholesale (clear + repopulate) in service-layer update methods; EAGER->LAZY mapping changes; merge/copy utilities clearing target maps; version upgrades that expose the queued path.

Related errors


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