hibernate/hibernate-orm · error · LazyInitializationException

Cannot lazily initialize collection (collection is being rem

Error message

Cannot lazily initialize collection (collection is being removed)

What it means

checkPersister runs while Hibernate initializes a collection and verifies a CollectionPersister is available. An uninitialized collection with a null persister only occurs when the collection is being torn down (its owner is being removed), so attempting initialization then fails with LazyInitializationException. It typically surfaces during delete or orphan-removal flushes over lazy, uninitialized collections.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java:672

			throwLazyInitializationException( "session is disconnected" );
		}
	}

	private void throwLazyInitializationException(String message) {
		final var error = new StringBuilder( "Cannot lazily initialize collection" );
		if ( role != null ) {
			error.append( " of role '" ).append( role ).append( "'" );
		}
		if ( key != null ) {
			error.append( " with key '" ).append( key ).append( "'" );
		}
		error.append( " (" ).append( message ).append( ")" );
		throw new LazyInitializationException( error.toString() );
	}

	public static void checkPersister(PersistentCollection<?> collection, CollectionPersister persister) {
		if ( !collection.wasInitialized() && persister == null ) {
			throw new LazyInitializationException( "Cannot lazily initialize collection"
													+ " (collection is being removed)" );
		}
	}

	protected final void setInitialized() {
		this.initializing = false;
		this.initialized = true;
	}

	@Override
	public boolean isInitializing() {
		return initializing;
	}

	protected final void setDirectlyAccessible(boolean directlyAccessible) {
		this.directlyAccessible = directlyAccessible;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Initialize the collection before deleting: Hibernate.initialize(owner.getItems()) inside the open session
  2. Load the entity fresh in the deleting session (session.get(...)) and then remove it
  3. Trim cascade and orphanRemoval scope to associations that genuinely need delete semantics
  4. If the mapping is clean and reproducible, check the Hibernate JIRA for your version and upgrade

Example fix

// before
em.remove(em.getReference(Order.class, id)); // lazy lines uninitialized -> throws during flush

// after
Order o = em.find(Order.class, id);
Hibernate.initialize(o.getLines());
em.remove(o);
Defensive patterns

Strategy: validation

Validate before calling

Order o = em.find(Order.class, id);
if (o.getLines() instanceof PersistentCollection pc && !pc.wasInitialized()) {
    Hibernate.initialize(o.getLines());
}
em.remove(o);

Try / catch

try {
    em.remove(order);
} catch (LazyInitializationException e) {
    if (e.getMessage() != null && e.getMessage().contains("being removed")) {
        Hibernate.initialize(order.getLines()); // reattach+init, then remove again
        em.remove(order);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Deleting an entity whose lazy collection is uninitialized while cascade processing needs its snapshot; @OneToMany(orphanRemoval = true) cascades forcing collection access during remove; merging or deleting detached instances loaded by another session.

Common situations: Cascade delete with orphanRemoval on lazy inverse collections; deleting detached graphs; edge cases in delete paths that are fixed in specific Hibernate versions.

Related errors


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