{"record":{"id":"785a8d7ef55644bb","repo":"hibernate/hibernate-orm","slug":"failed-to-discover-types-for-class-classname","errorCode":null,"errorMessage":"Failed to discover types for class {className}","messagePattern":"Failed to discover types for class (.+?)","errorType":"exception","errorClass":"EnhancementException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/EnhancerImpl.java","lineNumber":181,"sourceCode":"\t\t\tthrow new EnhancementException( \"Failed to enhance class \" + className, e );\n\t\t}\n\t\tfinally {\n\t\t\ttypePool.deregisterClassNameAndBytes( safeClassName );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void discoverTypes(String className, byte[] originalBytes) {\n\t\tif ( originalBytes != null ) {\n\t\t\ttypePool.registerClassNameAndBytes( className, originalBytes );\n\t\t}\n\t\ttry {\n\t\t\tfinal var typeDescription = typePool.describe( className ).resolve();\n\t\t\tenhancementContext.registerDiscoveredType( typeDescription, Type.PersistenceType.ENTITY );\n\t\t\tenhancementContext.discoverCompositeTypes( typeDescription, typePool );\n\t\t}\n\t\tcatch (RuntimeException e) {\n\t\t\tthrow new EnhancementException( \"Failed to discover types for class \" + className, e );\n\t\t}\n\t\tfinally {\n\t\t\ttypePool.deregisterClassNameAndBytes( className );\n\t\t}\n\t}\n\n\tprivate DynamicType.Builder<?> doEnhance(\n\t\t\tSupplier<DynamicType.Builder<?>> builderSupplier,\n\t\t\tTypeDescription managedCtClass) {\n\t\tif ( alreadyEnhanced( managedCtClass ) ) {\n\t\t\t// The class already implements `Managed`.\n\t\t\t// There are 2 broad cases:\n\t\t\t//\t\t1. the user manually implemented `Managed`\n\t\t\t//\t\t2. the class was previously enhanced\n\t\t\t// In either case, look for `@EnhancementInfo` and,\n\t\t\t// if found, verify we can \"re-enhance\" the class\n\t\t\tfinal var infoAnnotation =\n\t\t\t\t\tmanagedCtClass.getDeclaredAnnotations()","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/EnhancerImpl.java#L163-L199","documentation":"Before enhancing, the enhancer runs a discovery pass: EnhancerImpl.discoverTypes() registers the class bytes in the type pool, resolves the TypeDescription, then calls enhancementContext.discoverCompositeTypes(...) to walk embeddable/composite types. Any RuntimeException in that pass (typically unresolved types when describing the class or its referenced components) is wrapped as EnhancementException('Failed to discover types for class <name>').","triggerScenarios":"discoverTypes(className, originalBytes) where typePool.describe(className).resolve() cannot resolve the class from registered bytes, or discoverCompositeTypes hits an embeddable/superinterface that is not on the enhancement classpath (resolve() throws on unresolved descriptions).","commonSituations":"Gradle/Maven enhancement plugin configured without the project's runtime dependencies, so entities referencing other modules or jars fail type discovery; partial incremental builds where a dependent class's bytes are stale; fat-jar/shaded layouts hiding referenced types from the enhancer's loader.","solutions":["Read the cause chain to get the unresolved type name, then add the artifact containing it to the enhancement plugin's classpath.","Give the enhancement task the same classpath as compilation plus runtime dependencies (in Gradle: classpath = sourceSets.main.runtimeClasspath).","Run a clean build to rule out stale incremental class files feeding the type pool.","Upgrade hibernate-core if the failure is internal to discovery rather than a missing type."],"exampleFix":"// before (gradle)\nhibernateEnhance { classes { sourceSets.main.output } } // no classpath -> discovery fails\n\n// after\nhibernateEnhance {\n    classes { sourceSets.main.output }\n    classpath { sourceSets.main.runtimeClasspath } // embeddables/refs resolvable\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: every type referenced by the entity must resolve on the enhancement classpath\nstatic boolean discoverable(ClassLoader enhancerCl, String... typeNames) {\n    for ( String n : typeNames ) {\n        try { Class.forName( n, false, enhancerCl ); }\n        catch ( ClassNotFoundException e ) { return false; }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try { enhancer.discoverTypes( className, bytes ); }\ncatch ( EnhancementException e ) {\n    if ( e.getMessage() != null && e.getMessage().startsWith( \"Failed to discover types for class\" ) ) {\n        // cause names the unresolved type -> fix plugin classpath, not the entity code\n        buildLog.error( \"enhancement classpath incomplete: {}\", String.valueOf( e.getCause() ) );\n    }\n    throw e;\n}","preventionTips":["Configure the enhancement plugin with the full runtimeClasspath, not just compiled output.","Run enhancement after all contributing modules are compiled.","Treat 'Failed to discover types' as a classpath problem first - the entity source is rarely at fault."],"tags":["hibernate","bytecode-enhancement","classpath","build-time","type-resolution"],"backgroundTag":"bytecode-enhancement-failure","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}