quarkusio/quarkus · error · IllegalArgumentException
The '@Version' annotation cannot be used on primitive types.
Error message
The '@Version' annotation cannot be used on primitive types. Offending entity is '${entity}'. What it means
When generating the save() method, Quarkus distinguishes new vs existing entities by checking the @Version field. Spring Data JPA semantics require the version to be a nullable wrapper type (e.g. Long, Integer); a primitive version can never be null so newness cannot be detected. Quarkus rejects primitive @Version fields at augmentation time.
Source
Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/StockMethodsAdder.java:176
if (isPersistable(entityDotName)) {
Expr isNew = bc.invokeVirtual(
ClassMethodDesc.of(ClassDesc.of(entityDotName.toString()), "isNew",
MethodTypeDesc.of(ConstantDescs.CD_boolean)),
entityParam);
bc.ifElse(isNew,
tb -> generatePersistAndReturn(entityParam, tb, opsVar),
fb -> generateMergeAndReturn(entityParam, fb, opsVar,
entityClassVar));
} else {
AnnotationTarget idAnnotationTarget = getIdAnnotationTarget(entityDotName, index);
Expr idValue = generateObtainValue(bc, entityDotName, entityParam, idAnnotationTarget);
Type idType = getTypeOfTarget(idAnnotationTarget);
Optional<AnnotationTarget> versionValueTarget = getVersionAnnotationTarget(entityDotName, index);
if (versionValueTarget.isPresent()) {
Type versionType = getTypeOfTarget(versionValueTarget.get());
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.");View on GitHub (pinned to e1c734241f)
Solutions
- Change the @Version field type from primitive to its wrapper: int -> Integer, long -> Long
- Use java.util.Optional-friendly nullable types and adjust getters/setters accordingly
- If the schema column is NOT NULL, add a sensible default or let the persistence provider initialize the wrapper on insert
Example fix
// before @Version private long version; // after @Version private Long version;
Defensive patterns
Strategy: validation
Validate before calling
// Verify @Version field is a wrapper type at entity design time
Field v = MyEntity.class.getDeclaredField("version");
if (v.getType().isPrimitive())
throw new IllegalStateException("@Version must not be primitive: " + v.getType()); Type guard
boolean isValidVersionField(Field f) {
return f.isAnnotationPresent(jakarta.persistence.Version.class)
&& !f.getType().isPrimitive();
} Prevention
- Always declare @Version as Long/Integer (or java.util.Date/Instant/Timestamp)
- Add an ArchUnit or annotation-processing check for primitive @Version fields
- Review entity classes for optimistic-lock fields during code review
When it happens
Trigger: An entity has a field annotated @Version with a primitive type (int, long, short, etc.); calling save() on that repository triggers generation of the version-comparison logic.
Common situations: Defining optimistic-locking version columns with int/long instead of Integer/Long; porting entities from codebases where the provider tolerated primitives.
Related errors
- 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
- Currently the @Version annotation can only be placed on a si
- Method ${repositoryMethodDescription} cannot be parsed. Did
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/58add94c7ea5157e.
Report an issue: GitHub.