{"record":{"id":"4ea18330bca91830","repo":"hibernate/hibernate-orm","slug":"this-class-does-not-define-an-idclass","errorCode":null,"errorMessage":"This class [{}] does not define an IdClass","messagePattern":"This class \\[(.+?)\\] does not define an IdClass","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java","lineNumber":226,"sourceCode":"\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}\n\n\t@Override\n\t@Nonnull\n\tpublic Set<SingularAttribute<? super J, ?>> getIdClassAttributes() {\n\t\tif ( !hasIdClass() ) {\n\t\t\tthrow new IllegalArgumentException( \"This class [\" + getJavaType() + \"] does not define an IdClass\" );\n\t\t}\n\n\t\tfinal Set<SingularAttribute<? super J, ?>> attributes = new HashSet<>();\n\t\tvisitIdClassAttributes( attributes::add );\n\t\tif ( attributes.isEmpty() ) {\n\t\t\tthrow new IllegalArgumentException( \"Unable to locate IdClass attributes [\" + getJavaType() + \"]\" );\n\t\t}\n\t\treturn attributes;\n\t}\n\n\t@Override\n\tpublic void visitIdClassAttributes(@Nonnull Consumer<SingularPersistentAttribute<? super J, ?>> attributeConsumer) {\n\t\tif ( nonAggregatedIdAttributes != null ) {\n\t\t\tnonAggregatedIdAttributes.forEach( attributeConsumer );\n\t\t}\n\t\telse {\n\t\t\tfinal var superType = getSuperType();\n\t\t\tif ( superType != null ) {","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java#L208-L244","documentation":"getIdClassAttributes() is only meaningful for entities mapped with @IdClass. The implementation first asserts hasIdClass(); for entities using a single @Id or @EmbeddedId this is false and Hibernate throws IllegalArgumentException per the JPA specification (the spec requires IllegalStateException for this precondition, Hibernate uses IllegalArgumentException here — either way it signals wrong API choice).","triggerScenarios":"Calling identifiableType.getIdClassAttributes() on an entity that has a simple @Id or an @EmbeddedId instead of @IdClass. Generic key-handling code that unconditionally collects id-class attributes.","commonSituations":"Framework code that handles both key styles without checking hasIdClass() first. Changing an entity from @IdClass to @EmbeddedId without adapting callers.","solutions":["Branch on hasIdClass() before calling getIdClassAttributes()","For single-key entities use getId()/findIdAttribute(); for @EmbeddedId use the embedded id attribute","Consider visitIdClassAttributes(), which visits nothing instead of throwing when there is no id class"],"exampleFix":"// before\nSet<SingularAttribute<? super Order,?>> ids = orderType.getIdClassAttributes(); // @Id entity -> throws\n\n// after\nSet<SingularAttribute<? super Order,?>> ids =\n    orderType.hasIdClass()\n        ? orderType.getIdClassAttributes()\n        : Set.of(orderType.getId(orderType.getIdType().getJavaType()));","handlingStrategy":"validation","validationCode":"Set<SingularAttribute<? super E, ?>> idParts =\n    identifiableType.hasIdClass()\n        ? identifiableType.getIdClassAttributes()\n        : Set.of();","typeGuard":null,"tryCatchPattern":"try {\n    return type.getIdClassAttributes();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"does not define an IdClass\")) {\n        return Set.of(); // simple/embedded id: no id-class parts\n    }\n    throw e;\n}","preventionTips":["Check hasIdClass() before getIdClassAttributes() — one boolean prevents the exception","Model three key styles explicitly in key-resolution utilities: single, embedded, idclass","Prefer visitIdClassAttributes() for visitor-style code (no throw)"],"tags":["hibernate","jpa-metamodel","idclass","composite-key","illegal-argument"],"backgroundTag":"jpa-composite-id-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}