quarkusio/quarkus · error · IllegalArgumentException
Entity generic argument of ${repository} is not a regular cl
Error message
Entity generic argument of ${repository} is not a regular class type What it means
Quarkus resolves the repository's <E, ID> generic parameters against the extended Spring Data interface. The entity argument (first type parameter) must be a plain class type; type variables, wildcards, parameterized or array types cannot be used to generate queries. This error is thrown when the resolved entity argument is not a ClassType.
Source
Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/SpringDataRepositoryCreator.java:154
private Map.Entry<DotName, DotName> extractIdAndEntityTypes(ClassInfo repositoryToImplement, IndexView indexView) {
AnnotationInstance repositoryDefinitionInstance = repositoryToImplement
.declaredAnnotation(DotNames.SPRING_DATA_REPOSITORY_DEFINITION);
if (repositoryDefinitionInstance != null) {
return new AbstractMap.SimpleEntry<>(repositoryDefinitionInstance.value("idClass").asClass().name(),
repositoryDefinitionInstance.value("domainClass").asClass().name());
}
DotName entityDotName = null;
DotName idDotName = null;
// we need to pull the entity and ID types for the Spring Data generic types
// we also need to make sure that the user didn't try to specify multiple different types
// in the same interface (which is possible if only Repository is used)
for (DotName extendedSpringDataRepo : GenerationUtil.extendedSpringDataRepos(repositoryToImplement, indexView)) {
List<Type> types = JandexUtil.resolveTypeParameters(repositoryToImplement.name(), extendedSpringDataRepo, index);
if (!(types.get(0) instanceof ClassType)) {
throw new IllegalArgumentException(
"Entity generic argument of " + repositoryToImplement + " is not a regular class type");
}
DotName newEntityDotName = types.get(0).name();
if ((entityDotName != null) && !newEntityDotName.equals(entityDotName)) {
throw new IllegalArgumentException("Repository " + repositoryToImplement + " specifies multiple Entity types");
}
entityDotName = newEntityDotName;
DotName newIdDotName = types.get(1).name();
if ((idDotName != null) && !newIdDotName.equals(idDotName)) {
throw new IllegalArgumentException("Repository " + repositoryToImplement + " specifies multiple ID types");
}
idDotName = newIdDotName;
}
if (idDotName == null || entityDotName == null) {
throw new IllegalArgumentException(
"Repository " + repositoryToImplement + " does not specify ID and/or Entity type");View on GitHub (pinned to e1c734241f)
Solutions
- Make the repository's entity argument a concrete class: extends CrudRepository<MyEntity, Long>
- Remove generic intermediate layers or ensure the concrete type is resolved at the final repository interface (not left as a type variable)
- Do not use wildcards or parameterized types as the entity argument
Example fix
// before
class BaseRepo<T, ID> extends CrudRepository<T, ID> { }
interface FooRepo extends BaseRepo<Foo, Long> { } // resolution may still see T in some layouts
// after
interface FooRepo extends CrudRepository<Foo, Long> { } Defensive patterns
Strategy: validation
Validate before calling
// Entity argument must be a concrete class
interface UserRepo extends CrudRepository<User, Long> { } // good
// avoid: CrudRepository<? extends User, Long> or generic bases resolving to type variables Type guard
Class<?> entityType(Object repoGenericArg) {
return (repoGenericArg instanceof Class<?> c && !c.isInterface() && !c.getTypeParameters().length.isArrayType()) ? c : null;
} Prevention
- Never parameterize repositories with wildcards or type variables
- Flatten generic base repository hierarchies into concrete interfaces
- Resolve generics at the leaf repository interface
When it happens
Trigger: Declaring a repository whose first generic argument is a type variable, wildcard, generic type (e.g. Repo<T, Long> inside a generic superclass), or otherwise non-class type instead of a concrete @Entity class.
Common situations: Wrapping repositories in generic base classes/interfaces; using wildcards like CrudRepository<? extends Foo, Long>; intermediate generic layers where the entity type remains unresolved.
Related errors
- Repository ${repository} specifies multiple Entity types
- Repository ${repository} specifies multiple ID types
- Repository ${repository} does not specify ID and/or Entity t
- Unsupported wildcard type: ${wildcard}
- Invalid type:
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/dd2dfe861a998966.
Report an issue: GitHub.