{"record":{"id":"8fa061071f77e907","repo":"hibernate/hibernate-orm","slug":"unable-to-locate-id-type-for-type","errorCode":null,"errorMessage":"Unable to locate id type for type [{}]","messagePattern":"Unable to locate id type for type \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java","lineNumber":202,"sourceCode":"\n\t@Override\n\t@Nonnull\n\tpublic SimpleDomainType<?> getIdType() {\n\t\tfinal var id = findIdAttribute();\n\t\tif ( id != null ) {\n\t\t\treturn id.getType();\n\t\t}\n\t\telse {\n\t\t\tfinal var idClassAttributes = getIdClassAttributesSafely();\n\t\t\tif ( idClassAttributes != null ) {\n\t\t\t\tif ( idClassAttributes.size() == 1 ) {\n\t\t\t\t\treturn idClassAttributes.iterator().next().getType();\n\t\t\t\t}\n\t\t\t\telse if ( idClassType instanceof SimpleDomainType<?> simpleDomainType ) {\n\t\t\t\t\treturn simpleDomainType;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new IllegalStateException( \"Unable to locate id type for type [\" + getTypeName() + \"]\" );\n\t\t}\n\t}\n\n\t/**\n\t * A form of {@link #getIdClassAttributes} which prefers to return {@code null} rather than throw exceptions\n\t *\n\t * @return IdClass attributes or {@code null}\n\t */\n\tpublic Set<SingularPersistentAttribute<? super J, ?>> getIdClassAttributesSafely() {\n\t\tif ( hasIdClass() ) {\n\t\t\tfinal Set<SingularPersistentAttribute<? super J, ?>> attributes = new HashSet<>();\n\t\t\tvisitIdClassAttributes( attributes::add );\n\t\t\treturn attributes.isEmpty() ? null : attributes;\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\t}","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java#L184-L220","documentation":"getIdType() must return the simple domain type of the entity's identifier. It tries findIdAttribute(), then the @IdClass route (single id-class attribute, or the idClassType if it is a SimpleDomainType). If none apply — no id attribute anywhere in the hierarchy and no usable @IdClass type — Hibernate throws IllegalStateException, which almost always means the metadata is inconsistent or the type was built before its id mapping was wired up.","triggerScenarios":"Calling getIdType() during bootstrap before the id attribute was registered (metamodel built incrementally); on an embeddable or mapped-superclass incorrectly cast to an identifiable type; an @IdClass whose type is not resolvable as a SimpleDomainType with more than one attribute.","commonSituations":"Metamodel objects requested from the SessionFactory while mapping metadata is still being initialized (cyclic id references). Custom or programmatic mappings that forgot to declare an id. Bugs in older Hibernate 6.x versions during entity enhancement or lazy metadata init — upgrade if applicable.","solutions":["Verify the entity actually declares an id (@Id/@EmbeddedId/@IdClass) and that mapping is complete before querying the metamodel","Delay metamodel access until after SessionFactory/EntityManagerFactory bootstrap completes","If it reproduces on a stable mapping, check for a Hibernate version bug — update to the latest 6.x/7.x patch"],"exampleFix":"// before\nSimpleDomainType<?> idType = entityType.getIdType(); // during bootstrap -> may throw\n\n// after\n// access after factory build:\nEntityManagerFactory emf = Persistence.createEntityManagerFactory(\"pu\");\nSimpleDomainType<?> idType = emf.getMetamodel().entity(Order.class).getIdType();","handlingStrategy":"validation","validationCode":"// Only ask for id type on fully mapped identifiable types after bootstrap\nif (identifiableType.hasIdClass()) {\n    // ok: id type comes from the id class\n} else if (identifiableType.getId(...) == null) {\n    throw new IllegalStateException(\"entity missing id mapping: \" + identifiableType.getTypeName());\n}\nSimpleDomainType<?> idType = identifiableType.getIdType();","typeGuard":null,"tryCatchPattern":"try {\n    return type.getIdType();\n} catch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Unable to locate id type\")) {\n        // re-verify mapping; entity may lack an id or bootstrap is incomplete\n        throw new IllegalStateException(\"Mapping defect on \" + type.getTypeName(), e);\n    }\n    throw e;\n}","preventionTips":["Never query the metamodel while the SessionFactory is still initializing","Add schema-validation (hibernate.hbm2ddl.auto=validate) so mapping gaps surface at startup","Every @Entity must declare @Id, @EmbeddedId, or @IdClass — enforce with an ArchUnit test"],"tags":["hibernate","jpa-metamodel","bootstrap","id-mapping","illegal-state"],"backgroundTag":"jpa-metamodel-missing-id","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}