quarkusio/quarkus · error · IllegalArgumentException
Currently the @Version annotation can only be placed on a si
Error message
Currently the @Version annotation can only be placed on a single field or method. Offending class is ${entity} What it means
The extension supports at most one @Version annotation per entity hierarchy when generating optimistic-locking-aware save methods. If more than one @Version target is found on the entity or its superclasses, the build fails with this IllegalArgumentException because it cannot decide which version attribute to use.
Source
Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/StockMethodsAdder.java:1259
}
private Optional<AnnotationTarget> getVersionAnnotationTargetRec(DotName currentDotName, IndexView index,
DotName originalEntityDotName) {
ClassInfo classInfo = index.getClassByName(currentDotName);
if (classInfo == null) {
throw new IllegalStateException("Entity " + originalEntityDotName + " was not part of the Quarkus index");
}
if (!classInfo.annotationsMap().containsKey(DotNames.VERSION)) {
if (DotNames.OBJECT.equals(classInfo.superName())) {
return Optional.empty();
}
return getVersionAnnotationTargetRec(classInfo.superName(), index, originalEntityDotName);
}
List<AnnotationInstance> annotationInstances = classInfo.annotationsMap().get(DotNames.VERSION);
if (annotationInstances.size() > 1) {
throw new IllegalArgumentException(
"Currently the @Version annotation can only be placed on a single field or method. " +
"Offending class is " + originalEntityDotName);
}
return Optional.of(annotationInstances.get(0).target());
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Keep exactly one @Version field in the whole hierarchy; remove the rest
- Prefer the @Version in the abstract base entity and delete subclass duplicates
- Ensure @Version is on either the field or the getter, never both
- Use supported @Version types (int, Integer, long, Long, short, Short, java.sql.Timestamp, etc.)
Example fix
// before
class BaseEntity { @Version private long v1; }
@Entity class User extends BaseEntity { @Version private long v2; }
// after
class BaseEntity { @Version private long v1; }
@Entity class User extends BaseEntity { /* no second @Version */ } Defensive patterns
Strategy: validation
Validate before calling
// Ensure single @Version in hierarchy:
long v = java.util.Arrays.stream(User.class.getDeclaredFields())
.filter(f -> f.isAnnotationPresent(jakarta.persistence.Version.class)).count();
if (v > 1) throw new IllegalStateException("Multiple @Version fields in hierarchy"); Prevention
- Declare @Version only once, ideally in a shared base entity
- Add an ArchUnit rule banning multiple @Version fields
- Never annotate both field and getter with @Version
- Review superclass entities when adding version columns
When it happens
Trigger: Two fields annotated @Version within one hierarchy — e.g., a version field in the entity and another in a superclass, or @Version on both a field and its getter.
Common situations: Refactoring where a base entity already had @Version and a subclass added its own; copy-paste between entities; multiple inheritance levels each adding version columns.
Related errors
- The '@Version' annotation cannot be used on primitive types.
- Id type of '${entity}' is invalid.
- Currently only Entities with the @Id or @EmbeddedId annotati
- Currently the @Id or @EmbeddedId annotation can only be plac
- Method ${repositoryMethodDescription} cannot be parsed. Did
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d291c0086a76aa34.
Report an issue: GitHub.