{"record":{"id":"b59cf507a34cb937","repo":"quarkusio/quarkus","slug":"query-annotation-for-method-does-not-use-field","errorCode":null,"errorMessage":"@Query annotation for ${method} does not use fields from ${interface}","messagePattern":"@Query annotation for (.+?) does not use fields from (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/CustomQueryMethodsAdder.java","lineNumber":560,"sourceCode":"            for (Map.Entry<String, List<String>> queryMethod : queryMethods.entrySet().stream()\n                    .sorted(Map.Entry.comparingByKey()).toList()) {\n                MethodTypeDesc convertMtd = GenerationUtil.toMethodTypeDesc(implName.toString(), Object[].class.getName());\n                implClassCreator.staticMethod(\"convert_\" + queryMethod.getKey(), smc -> {\n                    smc.setType(convertMtd);\n                    smc.public_();\n                    ParamVar arrayParam = smc.parameter(\"input\");\n\n                    smc.body(bc -> {\n                        LocalVar newObject = bc.localVar(\"newObject\",\n                                bc.new_(ClassDesc.of(implName.toString())));\n\n                        // Use field names in the query-declared order\n                        List<String> queryNames = queryMethod.getValue();\n\n                        for (int i = 0; i < queryNames.size(); i++) {\n                            FieldDesc f = fields.get(queryNames.get(i));\n                            if (f == null) {\n                                throw new IllegalArgumentException(\"@Query annotation for \" + queryMethod.getKey()\n                                        + \" does not use fields from \" + interfaceName);\n                            } else {\n                                bc.set(newObject.field(f),\n                                        castReturnValue(bc, arrayParam.elem(i), f.type()));\n                            }\n                        }\n                        bc.return_(newObject);\n                    });\n                });\n            }\n        });\n    }\n\n    private Expr castReturnValue(BlockCreator bc, Expr resultHandle, ClassDesc type) {\n        String typeDesc = type.descriptorString();\n        switch (typeDesc) {\n            case \"I\":\n                resultHandle = bc.invokeStatic(","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/CustomQueryMethodsAdder.java#L542-L578","documentation":"For interface-based projections over custom @Query results, every selected column in the query must correspond to a getter/field of the projection interface, and conversely the fields the extension recorded for the query must exist in the interface. When a field name recorded from the @Query is not found among the projection interface's generated fields, this error is thrown at build time.","triggerScenarios":"The list of field names parsed from the @Query SELECT clause contains a name for which no matching getter exists on the projection interface (fields.get(name) returns null) in generateCustomResultTypes.","commonSituations":"Query selects u.userName but interface getter is getName(); typos in alias names; changing the interface getters without updating the query, or vice versa; queries selecting entities mixed with scalars.","solutions":["Align the JPQL SELECT aliases with the projection interface getter names (e.g. SELECT u.name AS name)","Rename the interface getter to match the selected column/alias","Add the missing getter for each selected column","Run the query mentally and enumerate its selected expressions, ensuring each has a matching interface property"],"exampleFix":"// before\n@Query(\"SELECT u.userName FROM User u\")\ninterface-based return UserView { String getName(); }\n\n// after\n@Query(\"SELECT u.userName AS name FROM User u\")\nList<UserView> ...; // UserView.getName() now matches alias 'name'","handlingStrategy":"validation","validationCode":"// every alias in the SELECT clause must have a matching getter in the projection interface\n// e.g. SELECT u.userName AS name  <=>  String getName();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Alias every selected expression explicitly and match getter names","Update query and projection interface together","Keep SELECT lists and interface getters in 1:1 correspondence"],"tags":["quarkus","spring-data-jpa","build-time","projection-interface","alias-mismatch"],"backgroundTag":"projection-field-mismatch","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"}