quarkusio/quarkus · error · IllegalArgumentException

Id type of '${entity}' is invalid.

Error message

Id type of '${entity}' is invalid.

What it means

Quarkus generates save() by comparing the ID field to determine whether to persist or merge. Only primitive long and primitive int ID types are supported for this comparison; any other primitive ID type (short, byte, char, etc.) cannot be reliably null-checked/compared and augmentation fails with this error.

Source

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

                                if (versionType instanceof PrimitiveType) {
                                    throw new IllegalArgumentException(
                                            "The '@Version' annotation cannot be used on primitive types. Offending entity is '"
                                                    + entityDotName + "'.");
                                }
                                Expr versionValue = generateObtainValue(bc, entityDotName, entityParam,
                                        versionValueTarget.get());
                                bc.ifElse(bc.isNull(versionValue),
                                        tb -> generatePersistAndReturn(entityParam, tb, opsVar),
                                        fb -> generateMergeAndReturn(entityParam, fb, opsVar,
                                                entityClassVar));
                                // if version is present, we've handled both branches, so return here
                                return;
                            }

                            if (idType instanceof PrimitiveType) {
                                if (!idType.name().equals(DotNames.PRIMITIVE_LONG)
                                        && !idType.name().equals(DotNames.PRIMITIVE_INTEGER)) {
                                    throw new IllegalArgumentException(
                                            "Id type of '" + entityDotName + "' is invalid.");
                                }
                                Expr idValueForComparison = idValue;
                                if (idType.name().equals(DotNames.PRIMITIVE_LONG)) {
                                    Expr longObject = bc.invokeStatic(
                                            MethodDesc.of(Long.class, "valueOf", Long.class, long.class), idValue);
                                    idValueForComparison = bc.invokeVirtual(
                                            MethodDesc.of(Long.class, "intValue", int.class), longObject);
                                }
                                // ifNonZero equivalent: if id != 0 => idValueSet, if id == 0 => idValueUnset
                                bc.ifElse(bc.ne(idValueForComparison, 0),
                                        idValueSetBlock -> generateMergeAndReturn(entityParam, idValueSetBlock,
                                                opsVar, entityClassVar),
                                        idValueUnsetBlock -> generatePersistAndReturn(entityParam,
                                                idValueUnsetBlock, opsVar));
                            } else {
                                bc.ifElse(bc.isNull(idValue),
                                        idValueUnsetBlock -> generatePersistAndReturn(entityParam,

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the @Id field to a supported type: primitive long or int, or preferably wrapper Long/Integer
  2. Wrapper types (Long/Integer) are safest since nullability drives persist-vs-merge
  3. Update getters/setters and any client code referencing the old ID type

Example fix

// before
@Id
private short id;
// after
@Id
private Long id;
Defensive patterns

Strategy: validation

Validate before calling

// Verify @Id field type before wiring a repository
Field id = MyEntity.class.getDeclaredField("id");
Class<?> t = id.getType();
if (!(t == Long.class || t == Integer.class || t == long.class || t == int.class))
    throw new IllegalStateException("Unsupported @Id type: " + t);

Type guard

boolean hasSupportedIdType(Field f) {
    Class<?> t = f.getType();
    return t == Long.class || t == Integer.class || t == long.class || t == int.class;
}

Prevention

When it happens

Trigger: An entity's @Id field is a primitive type other than long or int (e.g. short, char, byte); generating save()/saveAndFlush() for a repository of that entity hits the guard.

Common situations: Using unconventional primitive ID types; porting entities with compact numeric IDs; typos in ID field declarations.

Related errors


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