quarkusio/quarkus · error · IllegalArgumentException
${method.name()} of Repository ${repositoryClassInfo} is mea
Error message
${method.name()} of Repository ${repositoryClassInfo} is meant to be a delete query and can therefore only have a void or long return type What it means
A @Modifying query starting with 'delete' maps to JpaOperations.delete and may only return void, long, or java.lang.Long (the affected row count). Any other declared return type is rejected at build time with this IllegalArgumentException because there is no way to materialize other result shapes from a delete statement.
Source
Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/CustomQueryMethodsAdder.java:228
for (int i = 0; i < methodParameterTypes.size(); i++) {
params[i] = mc.parameter("p" + i);
}
mc.body(bc -> {
// Store static field and instance field in LocalVars so they can be reused
LocalVar ops = bc.localVar("ops", bc.getStaticField(operationsField));
LocalVar entityClass = bc.localVar("entityClass",
bc.get(mc.this_().field(entityClassFieldDescriptor)));
if (isModifying) {
AnnotationInstance modifyingAnnotation = method.annotation(DotNames.SPRING_DATA_MODIFYING);
handleFlushAutomatically(modifyingAnnotation, bc, entityClass);
if (finalQueryString.toLowerCase().startsWith("delete")) {
if (!DotNames.PRIMITIVE_LONG.equals(methodReturnTypeDotName)
&& !DotNames.LONG.equals(methodReturnTypeDotName)
&& !DotNames.VOID.equals(methodReturnTypeDotName)) {
throw new IllegalArgumentException(
method.name() + " of Repository " + repositoryClassInfo
+ " is meant to be a delete query and can therefore only have a void or long return type");
}
// we need to strip 'delete' or else JpaOperations.delete will generate the wrong query
String deleteQueryString = finalQueryString.substring("delete".length());
Expr deleteCount;
if (!finalNamedParameterToIndex.isEmpty()) {
Expr parameters = generateParametersObject(finalNamedParameterToIndex, bc, params);
// call JpaOperations.delete
deleteCount = bc.invokeVirtual(
MethodDesc.of(AbstractManagedJpaOperations.class, "delete", long.class,
Class.class, String.class, Parameters.class),
ops, entityClass,
Const.of(deleteQueryString), parameters);
} else {
Expr paramsArray = generateParamsArray(queryParameterIndexes, bc, params);View on GitHub (pinned to e1c734241f)
Solutions
- Change the return type to long, Long, or void
- Replace int/Integer with long/Long (Quarkus does not accept int for delete counts here)
- If no count is needed, declare void and ignore the return value
- Split the method: do a paginated/select query separately, then a void delete
Example fix
// before
@Modifying
@Query("delete from Token t where t.expiry < :now")
int deleteExpired(Instant now);
// after
@Modifying
@Query("delete from Token t where t.expiry < :now")
long deleteExpired(Instant now); Defensive patterns
Strategy: validation
Validate before calling
if (query.trim().toLowerCase().startsWith("delete")) {
Class<?> rt = method.getReturnType();
if (!(rt.equals(void.class) || rt.equals(long.class) || rt.equals(Long.class)))
throw new IllegalArgumentException("Delete @Query must return void or long/Long");
} Try / catch
try {
compile();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("delete query and can therefore only have")) {
log.error("Change return type to long/Long/void");
}
throw e;
} Prevention
- Declare delete @Query methods as long, Long, or void only
- Do not copy int-returning executeUpdate signatures into repositories
- Use void when the count is not needed
- Review return types when migrating between frameworks
When it happens
Trigger: A repository method with @Query("delete ...") (with or without @Modifying) declared to return int, Integer, boolean, List<T>, an entity type, or any type other than long/Long/void.
Common situations: Porting from JPA's executeUpdate() which returns int and declaring int in the repository; copy-pasting a select method signature; Spring allows int/Integer there while Quarkus's Spring Data layer is more restrictive and requires long/Long/void.
Related errors
- of Repository
- Method ${repositoryMethodDescription} cannot be parsed. Did
- Return type of method ${methodName} of Repository ${reposito
- ${t.name()} is not in the Quarkus Jandex index and cannot be
- spEL expressions are not currently supported. Offending meth
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e881fc99b2ccac85.
Report an issue: GitHub.