hibernate/hibernate-orm · error · HibernateException
Could not reassociate uninitialized transient collection
Error message
Could not reassociate uninitialized transient collection
What it means
HibernateException from ProxyVisitor.reattachCollection: while reattaching a detached entity's collection during lock/refresh-style reattach (the AbstractReattachEventListener proxy visitor path), an uninitialized PersistentCollection failed isCollectionSnapshotValid — its getRole() or getKey() is null. A collection wrapper with no role/key snapshot was never properly associated with a session, i.e. it is effectively transient, so there is nothing to reassociate it with.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/event/internal/ProxyVisitor.java:60
}
/**
* Reattach a detached (disassociated) initialized or uninitialized
* collection wrapper, using a snapshot carried with the collection
* wrapper
*/
protected void reattachCollection(@Nonnull PersistentCollection<?> collection, @Nonnull CollectionType type)
throws HibernateException {
final var session = getSession();
final var metamodel = session.getFactory().getMappingMetamodel();
final var context = session.getPersistenceContext();
if ( collection.wasInitialized() ) {
final var persister = metamodel.getCollectionDescriptor( type.getRole() );
context.addInitializedDetachedCollection( persister, collection );
}
else {
if ( !isCollectionSnapshotValid( collection ) ) {
throw new HibernateException( "Could not reassociate uninitialized transient collection" );
}
final var persister = metamodel.getCollectionDescriptor( collection.getRole() );
context.addUninitializedDetachedCollection( persister, collection );
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Use session.merge(entity) instead of lock()/update() for reattachment — merge copies state onto loaded instances and does not need the old wrapper's snapshot
- Ensure detached entities keep their original Hibernate collection instances (don't replace collection fields after load; don't deep-copy wrappers)
- For genuinely new entities, save/persist them instead of reattaching; fix the application logic that labels transient instances as detached
Example fix
// before // detached order whose items field was replaced with a plain ArrayList after load session.buildLockRequest(LockOptions.NONE).lock(order); // could not reassociate uninitialized transient collection // after Order managed = (Order) session.merge(order); // merge copies state, no snapshot needed
Defensive patterns
Strategy: fallback
Validate before calling
if (order instanceof HibernateProxy || Hibernate.isPropertyInitialized(order, "items")) {
if (order.getItems() != null && Hibernate.isInitialized(order.getItems())) {
// safe to reattach
}
}
// simplest: ensure managed collections stay attached by using merge() for detached graphs Type guard
boolean safeToReattach(Object entity, String collectionField) {
return Hibernate.isPropertyInitialized(entity, collectionField)
&& Hibernate.isInitialized(getter(entity, collectionField));
} Try / catch
try {
session.buildLockRequest(LockOptions.NONE).lock(order);
} catch (HibernateException e) {
if ("Could not reassociate uninitialized transient collection".equals(e.getMessage())) {
order = (Order) session.merge(order); // fallback: merge does not need the snapshot
} else { throw e; }
} Prevention
- Never replace entity collection fields with new java.util instances after load
- Use merge() (not update()/lock()) to reattach graphs of uncertain provenance
- Initialize needed lazy collections (Hibernate.initialize) before detaching entities across layers
When it happens
Trigger: session.lock(detachedEntity, LockMode.NONE) (or another reattach-based API) on a detached entity whose uninitialized lazy collection wrapper lost its snapshot — e.g. the collection field was replaced with a bare java.util collection that Hibernate wrapped fresh without a role/key, or a new entity instance with 'new ArrayList<>()' assigned is mistaken for detached state; deserialized/mutated wrappers whose role metadata is gone.
Common situations: Calling update()/lock() (reattach semantics) on entities that are actually transient or whose collection fields were swapped after load; mixing merge-style and update-style handling of the same object graph; deep-copy/serialization utilities that drop the PersistentCollection internals; upgrading code that relied on lenient reattachment behavior of older Hibernate versions.
Related errors
- Updating immutable entity that is not in session yet
- Named query definition is null
- Named query definition name is null: %s
- Duplicate named query '%s'
- Named native query definition object is null
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/817fff4fcd549985.
Report an issue: GitHub.