hibernate/hibernate-orm · error · IllegalArgumentException
The version attribute is not declared or inherited by this t
Error message
The version attribute is not declared or inherited by this type [{}] What it means
getVersion(Class) requires an @Version attribute either declared on or inherited by the type; findVersionAttribute() walks the hierarchy and returns null when there is none. Hibernate then throws IllegalArgumentException. Entities with optimistic locking disabled (@OptimisticLocking or simply no @Version field) hit this.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java:272
}
public boolean hasDeclaredVersionAttribute() {
return isVersioned && versionAttribute != null;
}
@Override
@Nonnull
public <Y> SingularPersistentAttribute<? super J, Y> getVersion(@Nonnull Class<Y> javaType) {
if ( hasVersionAttribute() ) {
final var version = findVersionAttribute();
if ( version != null ) {
checkType( version, javaType );
@SuppressWarnings("unchecked") // safe, we just checked
final var castVersion = (SingularPersistentAttribute<? super J, Y>) version;
return castVersion;
}
}
throw new IllegalArgumentException(
"The version attribute is not declared or inherited by this type [" + getJavaType() + "]"
);
}
@Override
@Nullable
public SqmSingularPersistentAttribute<? super J, ?> findVersionAttribute() {
if ( versionAttribute != null ) {
return versionAttribute;
}
else if ( getSuperType() != null ) {
return getSuperType().findVersionAttribute();
}
else {
return null;
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Check hasVersionAttribute() (or nullable findVersionAttribute()) before calling getVersion(Class)
- Add @Version private Long version; to the entity if optimistic versioning is actually wanted
- In generic code treat a missing version as 'no optimistic lock' rather than an error
Example fix
// before
var v = entityType.getVersion(Long.class); // entity has no @Version -> throws
// after
if (entityType.hasVersionAttribute()) {
var v = entityType.getVersion(Long.class);
} else {
// unversioned entity: rely on dirty-check locking
} Defensive patterns
Strategy: validation
Validate before calling
if (identifiableType.hasVersionAttribute()) {
var version = identifiableType.getVersion(versionJavaType(identifiableType));
} else {
// unversioned: use dirty-check or all-column optimistic locking
} Try / catch
try {
return type.getVersion(cls);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("version attribute is not declared or inherited")) {
return null; // entity is not versioned
}
throw e;
} Prevention
- Guard getVersion() with hasVersionAttribute()
- Prefer nullable findVersionAttribute() in optional contexts
- Centralize optimistic-lock support detection per entity in one utility
When it happens
Trigger: Calling entityType.getVersion(Integer.class) on an entity with no @Version column; generic optimistic-locking helpers that assume every entity is versioned.
Common situations: Adding a version-audit utility to a codebase where only some entities are @Version-annotated. Entities relying on timestamp or all-column optimistic locking instead of a version column.
Related errors
- Illegal call to IdentifiableType#getId for class [{}] define
- Attribute [%s#%s : %s] not castable to requested type [%s]
- This class [{}] does not define an IdClass
- The version attribute is not declared by this type [{}]
- Unable to locate %s with the given name [%s] on this Managed
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3d079026fc03e2c4.
Report an issue: GitHub.