{"record":{"id":"d017fa92ea0d8a21","repo":"quarkusio/quarkus","slug":"currently-the-id-or-embeddedid-annotation-can-on","errorCode":null,"errorMessage":"Currently the @Id or @EmbeddedId annotation can only be placed on a single field or method. Offending class is ${entity}","messagePattern":"Currently the @Id or @EmbeddedId annotation can only be placed on a single field or method\\. Offending class is (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/StockMethodsAdder.java","lineNumber":1231,"sourceCode":"            throw new IllegalStateException(\"Entity \" + originalEntityDotName + \" was not part of the Quarkus index\");\n        }\n\n        List<AnnotationInstance> annotationInstances = Stream.of(DotNames.JPA_ID, DotNames.JPA_EMBEDDED_ID)\n                .map(classInfo.annotationsMap()::get)\n                .filter(Objects::nonNull)\n                .flatMap(List::stream)\n                .collect(Collectors.toList());\n        if (annotationInstances.isEmpty()) {\n            if (DotNames.OBJECT.equals(classInfo.superName())) {\n                throw new IllegalArgumentException(\n                        \"Currently only Entities with the @Id or @EmbeddedId annotation are supported. Offending class is \"\n                                + originalEntityDotName);\n            }\n            return getIdAnnotationTargetRec(classInfo.superName(), index, originalEntityDotName);\n        }\n\n        if (annotationInstances.size() > 1) {\n            throw new IllegalArgumentException(\n                    \"Currently the @Id or @EmbeddedId annotation can only be placed on a single field or method. \" +\n                            \"Offending class is \" + originalEntityDotName);\n        }\n\n        return annotationInstances.get(0).target();\n    }\n\n    private Optional<AnnotationTarget> getVersionAnnotationTarget(DotName entityDotName, IndexView index) {\n        return getVersionAnnotationTargetRec(entityDotName, index, entityDotName);\n    }\n\n    private Optional<AnnotationTarget> getVersionAnnotationTargetRec(DotName currentDotName, IndexView index,\n            DotName originalEntityDotName) {\n        ClassInfo classInfo = index.getClassByName(currentDotName);\n        if (classInfo == null) {\n            throw new IllegalStateException(\"Entity \" + originalEntityDotName + \" was not part of the Quarkus index\");\n        }\n","sourceCodeStart":1213,"sourceCodeEnd":1249,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/StockMethodsAdder.java#L1213-L1249","documentation":"The extension supports at most one @Id or @EmbeddedId annotation per entity hierarchy when generating repository code. If more than one @Id/@EmbeddedId target is found on the entity (across fields/methods and superclasses), the build fails with this IllegalArgumentException, because the generated code would not know which attribute is the identifier.","triggerScenarios":"Two fields annotated @Id in the same class; an @Id in the entity plus another @Id in a superclass; both @Id and @EmbeddedId present; @Id placed on both a field and its getter.","commonSituations":"Merging entity classes after refactoring; copying JPA code that used Hibernate's multiple-id support; attempting composite keys with several @Id fields instead of @EmbeddedId/@IdClass.","solutions":["Keep exactly one @Id (or one @EmbeddedId) per entity hierarchy and remove the others","For composite keys, use a single @EmbeddedId with an @Embeddable key class, or @IdClass with a single @Id reference pattern per JPA spec","If id is defined in a superclass, delete the duplicate in the subclass","Move the annotation to the getter only, or the field only, not both"],"exampleFix":"// before\n@Entity\npublic class User {\n    @Id private Long id;\n    @Id private String email; // duplicate\n}\n\n// after\n@Entity\npublic class User {\n    @Id private Long id;\n    private String email;\n}","handlingStrategy":"validation","validationCode":"// Assert exactly one id annotation in the hierarchy:\nlong idCount = java.util.Arrays.stream(User.class.getDeclaredFields())\n    .filter(f -> f.isAnnotationPresent(jakarta.persistence.Id.class)\n        || f.isAnnotationPresent(jakarta.persistence.EmbeddedId.class)).count();\nif (idCount != 1) throw new IllegalStateException(\"Entity must have exactly one @Id/@EmbeddedId\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One @Id per hierarchy — enforce with a unit test or ArchUnit rule","Use @EmbeddedId for composite keys instead of multiple @Id","Check superclass entities before adding id fields to subclasses","Never annotate both the field and getter of the same id"],"tags":["quarkus","spring-data-jpa","jpa","entity-mapping","build-time"],"backgroundTag":"duplicate-jpa-id-annotation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}