{"record":{"id":"fe7484478569e8c6","repo":"hibernate/hibernate-orm","slug":"enhancement-requires-a-temp-class-loader-but-none","errorCode":null,"errorMessage":"Enhancement requires a temp class loader, but none was given [persistence unit: {}] ","messagePattern":"Enhancement requires a temp class loader, but none was given \\[persistence unit: (.+?)\\] ","errorType":"exception","errorClass":"PersistenceException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java","lineNumber":438,"sourceCode":"\t\tif ( !lazyInitializationEnabled ) {\n\t\t\tDEPRECATION_LOGGER.deprecatedSettingForRemoval( ENHANCER_ENABLE_LAZY_INITIALIZATION, \"true\" );\n\t\t}\n\t\tif ( !dirtyTrackingEnabled ) {\n\t\t\tDEPRECATION_LOGGER.deprecatedSettingForRemoval( ENHANCER_ENABLE_DIRTY_TRACKING, \"true\" );\n\t\t}\n\n\t\tif ( dirtyTrackingEnabled || lazyInitializationEnabled || associationManagementEnabled ) {\n\t\t\tfinal var enhancementContext =\n\t\t\t\t\tgetEnhancementContext( dirtyTrackingEnabled,\n\t\t\t\t\t\t\tlazyInitializationEnabled,\n\t\t\t\t\t\t\tassociationManagementEnabled );\n\t\t\t// push back class transformation to the environment; for the time being this only has any effect in EE\n\t\t\t// container situations, calling back into PersistenceUnitInfo#addClassTransformer\n\t\t\tfinal var classTransformer = persistenceUnit.pushClassTransformer( enhancementContext );\n\t\t\tif ( classTransformer != null ) {\n\t\t\t\tfinal var classLoader = persistenceUnit.getTempClassLoader();\n\t\t\t\tif ( classLoader == null ) {\n\t\t\t\t\tthrow new PersistenceException( \"Enhancement requires a temp class loader, but none was given\"\n\t\t\t\t\t\t\t+ exceptionHeader() );\n\t\t\t\t}\n\t\t\t\tdiscoverTypesToTransform( metadataSources, classTransformer, classLoader );\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static void discoverTypesToTransform(\n\t\t\tMetadataSources metadataSources, ClassTransformer classTransformer, ClassLoader classLoader) {\n\t\tfor ( var binding : metadataSources.getHbmXmlBindings() ) {\n\t\t\tfinal var hibernateMapping = binding.getRoot();\n\t\t\tfinal String packageName = hibernateMapping.getPackage();\n\t\t\tfor ( var clazz : hibernateMapping.getClazz() ) {\n\t\t\t\tfinal String className =\n\t\t\t\t\t\tpackageName == null || packageName.isEmpty()\n\t\t\t\t\t\t\t\t? clazz.getName()\n\t\t\t\t\t\t\t\t: packageName + '.' + clazz.getName();\n\t\t\t\ttry {","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java#L420-L456","documentation":"The EntityManagerFactoryBuilderImpl path for runtime enhancement: after a ClassTransformer is pushed to the environment (EE container callback), Hibernate asks PersistenceUnitInfo.getTempClassLoader() for a classloader to discover types to transform. If that method returns null while enhancement features are enabled, bootstrap fails with this PersistenceException (the unit name is appended via exceptionHeader()).","triggerScenarios":"Runtime enhancement active (hibernate.enhancer.enableDirtyTracking / enableLazyInitialization / enableAssociationManagement not all false) in a container whose PersistenceUnitInfo returns null from getTempClassLoader(), after a class transformer was successfully registered.","commonSituations":"Servlet containers or lightweight SE runtimes that implement PersistenceUnitInfo partially (getTempClassLoader returns null by design in several implementations); custom test harnesses enabling enhancement at runtime.","solutions":["Move enhancement to build time (Hibernate Gradle/Maven plugin) and set the three hibernate.enhancer.enable* settings to false","Or implement getTempClassLoader() in your PersistenceUnitInfo to return a dedicated throwaway ClassLoader","Verify the container actually supports runtime class transformation before enabling enhancer settings"],"exampleFix":"// before: runtime enhancement enabled, getTempClassLoader() returns null -> PersistenceException\n\n// after (option A: implement the SPI)\nclass MyPersistenceUnitInfo implements PersistenceUnitInfo {\n    @Override public ClassLoader getTempClassLoader() {\n        return new URLClassLoader(classpathUrls, getClass().getClassLoader()); // never null\n    }\n}\n// after (option B): build-time enhancement + disable runtime flags\n// props.put(\"hibernate.enhancer.enableDirtyTracking\", \"false\"); ...","handlingStrategy":"validation","validationCode":"// Either opt out of runtime enhancement (preferred in SE/servlet containers)\nprops.put(\"hibernate.enhancer.enableDirtyTracking\", \"false\");\nprops.put(\"hibernate.enhancer.enableLazyInitialization\", \"false\");\nprops.put(\"hibernate.enhancer.enableAssociationManagement\", \"false\");\n// or, in your PersistenceUnitInfo, never return null:\n// @Override public ClassLoader getTempClassLoader() {\n//     return new URLClassLoader(classpathUrls, getClass().getClassLoader());\n// }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enhance entities at build time; runtime enhancement is an EE-container feature","Implement getTempClassLoader() with a dedicated disposable classloader, not null","Test the full bootstrap path on the container profile you ship to"],"tags":["jpa","bytecode-enhancement","classloader","bootstrap"],"backgroundTag":"bytecode-enhancement-misconfigured","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}