quarkusio/quarkus · error · IllegalArgumentException

Method ${method} of interface ${interface} is not a getter m

Error message

Method ${method} of interface ${interface} is not a getter method since it returns void

What it means

When a custom @Query returns a non-entity type, it must be an interface whose methods are all valid getters returning non-void types; the extension generates a class implementing the interface and maps query columns to fields. A method on the projection interface that returns void cannot be turned into a field, so the build throws this error in generateCustomResultTypes.

Source

Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/CustomQueryMethodsAdder.java:519

        ClassInfo interfaceInfo = index.getClassByName(interfaceName);

        Gizmo gizmo = Gizmo.create(nonBeansClassOutput);
        gizmo.class_(implName.toString(), implClassCreator -> {
            implClassCreator.implements_(ClassDesc.of(interfaceName.toString()));

            // Add default constructor
            implClassCreator.defaultConstructor();

            Map<String, FieldDesc> fields = new HashMap<>(3);

            for (MethodInfo method : interfaceInfo.methods()) {
                String getterName = method.name();
                String propertyName = JavaBeanUtil.getPropertyNameFromGetter(getterName);

                Type returnType = method.returnType();
                if (returnType.kind() == Type.Kind.VOID) {
                    throw new IllegalArgumentException("Method " + method.name() + " of interface " + interfaceName
                            + " is not a getter method since it returns void");
                }
                DotName fieldTypeName = getPrimitiveTypeName(returnType.name());

                FieldDesc field = implClassCreator.field(propertyName, ifc -> {
                    ifc.setType(GenerationUtil.toClassDesc(fieldTypeName.toString()));
                });

                // create getter (based on the interface)
                MethodTypeDesc getterMtd = GenerationUtil.toMethodTypeDesc(returnType.name().toString());
                implClassCreator.method(getterName, mc -> {
                    mc.setType(getterMtd);
                    mc.public_();
                    mc.body(bc -> {
                        bc.return_(bc.get(mc.this_().field(field)));
                    });
                });

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the void-returning method from the projection interface
  2. Rename the method to a proper getter (getX()/isX()) with a matching non-void return type
  3. Keep only getter methods in projection interfaces
  4. Move any behavior/logic methods out of the projection interface into a separate utility or default method if truly needed

Example fix

// before
interface UserView {
  String getName();
  void setName(String name);
}

// after
interface UserView {
  String getName();
}
Defensive patterns

Strategy: validation

Validate before calling

for (Method m : projection.getMethods()) {
  if (m.getReturnType() == void.class) throw new AssertionError(m + " must be a getter");
}

Prevention

When it happens

Trigger: Declaring a projection interface with a void-returning method (or a non-getter method returning void, e.g. a setter or default-looking method) used as the return type of a @Query method.

Common situations: Including setters or helper void methods in a projection interface; copying a full interface with mutators from a DTO class converted to an interface.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7b3876919dd9d2c3. Report an issue: GitHub.