{"record":{"id":"beb73d8a776ade78","repo":"hibernate/hibernate-orm","slug":"force-initializing-collection-loading","errorCode":null,"errorMessage":"force initializing collection loading","messagePattern":"force initializing collection loading","errorType":"exception","errorClass":"AssertionFailure","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java","lineNumber":847,"sourceCode":"\t\t// the param would have to be bound twice.  Until we eventually add \"parameter bind points\" concepts to the\n\t\t// AST in ORM 5+, handling this type of condition is either extremely difficult or impossible.  Forcing\n\t\t// recreation isn't ideal, but not really any other option in ORM 4.\n\t\t// Selecting a type used in where part of update statement\n\t\t// (must match condition in org.hibernate.persister.collection.BasicCollectionPersister#doUpdateRows).\n\t\t// See HHH-9474\n\t\tfinal Type whereType =\n\t\t\t\tpersister.hasIndex()\n\t\t\t\t\t\t? persister.getIndexType()\n\t\t\t\t\t\t: persister.getElementType();\n\t\treturn whereType instanceof CompositeType compositeType\n\t\t\t&& compositeType.hasNullProperty();\n\t}\n\n\t@Override\n\tpublic final void forceInitialization() throws HibernateException {\n\t\tif ( !initialized ) {\n\t\t\tif ( initializing ) {\n\t\t\t\tthrow new AssertionFailure( \"force initializing collection loading\" );\n\t\t\t}\n\t\t\tinitialize( false );\n\t\t}\n\t}\n\n\n\t/**\n\t * Get the current snapshot from the session\n\t */\n\tprotected final Serializable getSnapshot() {\n\t\treturn session.getPersistenceContext().getSnapshot( this );\n\t}\n\n\t@Override\n\tpublic final boolean wasInitialized() {\n\t\treturn initialized;\n\t}\n","sourceCodeStart":829,"sourceCodeEnd":865,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java#L829-L865","documentation":"forceInitialization fully loads a collection (used by cascading actions and lazy-state handling). If the collection is already mid-initialization, re-entering initialize would recurse, so Hibernate throws AssertionFailure. This is a reentrancy problem: loading collection A triggers, through listeners, bidirectional cascades, or eager cycles, a force-initialization of A itself.","triggerScenarios":"Event listeners or interceptors that initialize collections during onLoad/onLoadCollection; bidirectional relations eager-fetched on both sides forming a cycle; bytecode enhancement interacting with custom loaders; rare internal bugs in specific versions.","commonSituations":"Custom load-time listeners touching associations; circular fetch-join graphs; behavior changes after a Hibernate upgrade.","solutions":["Break the cycle: make one side of the bidirectional association lazy and drop mapping-level eager fetch","Remove collection initialization from load-time event listeners and interceptors","Prefer query-level join fetch over mapping-level eager fetching for the paths that need data","Reproduce with a minimal mapping and check/report on the Hibernate JIRA - AssertionFailure marks an internal invariant break"],"exampleFix":"// before: eager on both sides of a bidirectional relation\n@OneToMany(mappedBy = \"parent\", fetch = FetchType.EAGER)\nList<Child> children;\n@ManyToOne(fetch = FetchType.EAGER) Parent parent;\n\n// after\n@OneToMany(mappedBy = \"parent\", fetch = FetchType.LAZY)\nList<Child> children; // fetch explicitly with 'join fetch' where needed","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid eager fetch on both sides of a bidirectional relation","Never initialize collections inside load-time event listeners or interceptors","Keep cascade graphs shallow; prefer explicit queries over deep eager graphs","Treat AssertionFailure with 'force initializing collection loading' as a design smell to fix, not to catch"],"tags":["hibernate","lazy-loading","assertion","reentrancy","circular-reference"],"backgroundTag":"reentrant-lazy-initialization","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}