quarkusio/quarkus · error · IllegalArgumentException

Repository ${repository} specifies multiple ID types

Error message

Repository ${repository} specifies multiple ID types

What it means

Analogous to the entity mismatch check, Quarkus requires all Spring Data interfaces extended by a repository to resolve to the same ID type. If the ID generic argument differs across the hierarchy (e.g. Long in one parent, UUID in another), the generated implementation cannot be typed consistently and augmentation fails.

Source

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

        // 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");
        }

        return new AbstractMap.SimpleEntry<>(idDotName, entityDotName);
    }

    private void createCustomImplFields(io.quarkus.gizmo2.creator.ClassCreator repositoryImpl,
            List<DotName> customInterfaceNamesToImplement,
            IndexView index, Map<String, FieldDesc> customImplNameToFieldDescriptor) {
        Set<String> customImplClassNames = new HashSet<>(customInterfaceNamesToImplement.size());

        // go through the interfaces and collect the implementing classes in a Set

View on GitHub (pinned to e1c734241f)

Solutions

  1. Make all parent Spring Data interfaces use the same ID type parameter
  2. Update any stale parent interface to the entity's actual @Id field type
  3. Keep one repository interface per entity/ID combination

Example fix

// before
interface UserRepo extends CrudRepository<User, Long>, Repository<User, UUID> { }
// after
interface UserRepo extends CrudRepository<User, Long> { }
Defensive patterns

Strategy: validation

Validate before calling

// ID type must match the entity's @Id field across all parents
// e.g. @Id private Long id; => CrudRepository<User, Long> everywhere

Prevention

When it happens

Trigger: A repository extends interfaces parameterized with different ID types, e.g. CrudRepository<User, Long> plus a custom base extending Repository<User, UUID>.

Common situations: Changing an entity's @Id type and forgetting one parent interface; mixing repository fragments with different ID generics; copy-pasted base interfaces.

Related errors


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