{"record":{"id":"bdc0f462aa72f9be","repo":"hibernate/hibernate-orm","slug":"queued-clear-cannot-be-used-with-orphan-delete-bdc0f4","errorCode":null,"errorMessage":"queued clear cannot be used with orphan delete","messagePattern":"queued clear cannot be used with orphan delete","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentSet.java","lineNumber":460,"sourceCode":"\t@Override\n\tpublic boolean isWrapper(Object collection) {\n\t\treturn set==collection;\n\t}\n\n\tfinal class Clear implements DelayedOperation<E> {\n\t\t@Override\n\t\tpublic void operate() {\n\t\t\tset.clear();\n\t\t}\n\n\t\t@Override\n\t\tpublic E getAddedInstance() {\n\t\t\treturn null;\n\t\t}\n\n\t\t@Override\n\t\tpublic E getOrphan() {\n\t\t\tthrow new UnsupportedOperationException(\"queued clear cannot be used with orphan delete\");\n\t\t}\n\t}\n\n\tfinal class SimpleAdd extends AbstractValueDelayedOperation {\n\n\t\tpublic SimpleAdd(E addedValue) {\n\t\t\tsuper( addedValue, null );\n\t\t}\n\n\t\t@Override\n\t\tpublic void operate() {\n\t\t\tset.add( getAddedInstance() );\n\t\t}\n\t}\n\n\tfinal class SimpleRemove extends AbstractValueDelayedOperation {\n\n\t\tpublic SimpleRemove(E orphan) {","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentSet.java#L442-L478","documentation":"PersistentSet queues operations on an uninitialized lazy collection, so clear() on an uninitialized set becomes a queued Clear operation. A bulk Clear cannot enumerate removed elements, so when the association has orphan delete enabled (orphanRemoval=true / delete-orphan) and flush asks the queued operation for its orphan via getOrphan(), it throws UnsupportedOperationException. Set flavor of the same limitation as PersistentList/PersistentMap.","triggerScenarios":"@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) Set<Tag> tags; parent loaded without touching tags; tags.clear() called (e.g. replacing all tags); flush needs orphan deletion.","commonSituations":"Tag/role replacement flows that clear the whole set and re-add; EAGER->LAZY mapping changes; bulk edit screens saving empty sets; upgrading Hibernate where the queued path becomes reachable.","solutions":["Initialize before clearing: Hibernate.initialize(parent.getTags()) or call size() first","Clear by individual removal on the initialized set (removeIf/iterator) so orphans are tracked per element","Drop orphanRemoval=true where clear-all is the normal write pattern","Test the replace-all flow end-to-end including flush"],"exampleFix":"// before\nparent.getTags().clear();      // uninitialized PersistentSet -> queued Clear\nparent.getTags().addAll(newTags);\ntx.commit();                   // flush -> UnsupportedOperationException\n\n// after\nHibernate.initialize(parent.getTags());\nparent.getTags().clear();\nparent.getTags().addAll(newTags);","handlingStrategy":"validation","validationCode":"Set<Tag> tags = parent.getTags();\nif (tags instanceof org.hibernate.collection.spi.PersistentCollection pc && !pc.wasInitialized()) {\n    org.hibernate.Hibernate.initialize(tags);\n}\ntags.clear();","typeGuard":null,"tryCatchPattern":"try {\n    tx.commit();\n} catch (org.hibernate.HibernateException e) {\n    Throwable c = e;\n    while (c != null) {\n        if (c instanceof UnsupportedOperationException && String.valueOf(c.getMessage()).contains(\"queued clear\")) {\n            throw new IllegalStateException(\"clear() on uninitialized set with orphanRemoval; initialize first\", e);\n        }\n        c = c.getCause();\n    }\n    throw e;\n}","preventionTips":["Initialize lazy sets before clear() when orphanRemoval=true","Use removeIf for tag-replacement flows so orphans are tracked","Cover replace-all set updates with a flushing integration test"],"tags":["hibernate","collections","orphan-removal","lazy-initialization","persistent-set","flush"],"backgroundTag":"orphan-removal-queued-clear","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}