quarkusio/quarkus · error · IllegalArgumentException
Query annotations may only use interfaces to map results to
Error message
Query annotations may only use interfaces to map results to non-entity types. Offending query string is "${query}" on method ${method} of Repository ${repository} What it means
The Quarkus Spring Data JPA extension only supports mapping custom @Query results to non-entity types when the return type is an interface, for which it generates an implementation at build time. If the method returns a non-entity class (e.g. a POJO/DTO class) with a custom query, the extension cannot map columns to its fields, so it throws this error during augmentation.
Source
Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/CustomQueryMethodsAdder.java:355
|| getFieldTypeNames(entityClassInfo, entityFieldTypeNames).contains(customResultTypeName)) {
// no special handling needed
customResultTypeName = null;
} else {
// The result is using a custom type.
List<String> fieldNames = getFieldNames(finalQueryString);
// If the custom type is an interface, we need to generate the implementation
ClassInfo resultClassInfo = index.getClassByName(customResultTypeName);
if (Modifier.isInterface(resultClassInfo.flags())) {
// Find the implementation name, and use that for subsequent query result generation
customResultTypeName = customResultTypeNames.computeIfAbsent(customResultTypeName,
(k) -> createSimpleInterfaceImpl(k, entityClassInfo.name()));
// Remember the parameters for this usage of the custom type, we'll deal with it later
customResultTypes.computeIfAbsent(customResultTypeName,
k -> new HashMap<>()).put(methodName, fieldNames);
} else {
throw new IllegalArgumentException(
"Query annotations may only use interfaces to map results to non-entity types. "
+ "Offending query string is \"" + finalQueryString + "\" on method "
+ methodName
+ " of Repository " + repositoryName);
}
}
Expr panacheQuery;
if (!finalNamedParameterToIndex.isEmpty()) {
Expr parameters = generateParametersObject(finalNamedParameterToIndex, bc, params);
// call JpaOperations.find()
panacheQuery = bc.invokeStatic(
MethodDesc.of(AdditionalJpaOperations.class, "find",
PanacheQuery.class, AbstractManagedJpaOperations.class, Class.class, String.class,
String.class, io.quarkus.panache.common.Sort.class, Parameters.class),
ops, entityClass,
Const.of(finalQueryString), Const.of(countQueryString),View on GitHub (pinned to e1c734241f)
Solutions
- Convert the projection class to an interface with getter methods matching the selected columns
- Use constructor expression in JPQL (SELECT new com.example.Dto(e.a, e.b)) and keep the class return type
- Make the returned type a managed @Entity if it should be an entity projection
- Split the query so the repository returns entities and map to DTOs in application code
Example fix
// before
class UserDto { private String name; public String getName() {...} }
@Query("SELECT u.name FROM User u")
List<UserDto> findNames();
// after
interface UserDto { String getName(); }
@Query("SELECT u.name FROM User u")
List<UserDto> findNames(); Defensive patterns
Strategy: validation
Validate before calling
// projection return types of @Query methods must be interfaces (or entities) boolean ok = returnType.isInterface();
Prevention
- Always model projections as interfaces
- Use SELECT new ... constructor expressions for class DTOs
- Keep entity vs DTO return types documented per repository
When it happens
Trigger: A repository method annotated with @Query whose declared return type is a concrete (non-interface, non-entity) class, encountered in CustomQueryMethodsAdder.add while resolving custom result types.
Common situations: Returning a DTO class from a custom JPQL query; migrating from Spring where class-based DTO projection with a constructor worked; defining a projection class instead of an interface.
Related errors
- 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
- Unsupported query type in @Query. Offending method is ${meth
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2148944ef768e4a9.
Report an issue: GitHub.