hibernate/hibernate-orm · error · IllegalArgumentException

The version attribute is not declared by this type [{}]

Error message

The version attribute is not declared by this type [{}]

What it means

getDeclaredVersion(Class) must return a version attribute declared on the type itself. checkDeclaredVersion() throws when versionAttribute == null OR when a supertype already declares the version (inherited versions are not 'declared'). This mirrors the declared-vs-inherited distinction of the JPA metamodel API.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java:317

		}
		else {
			return null;
		}
	}

	@Override
	@Nonnull
	public <Y> SingularPersistentAttribute<J, Y> getDeclaredVersion(@Nonnull Class<Y> javaType) {
		checkDeclaredVersion();
		checkType( versionAttribute, javaType );
		@SuppressWarnings("unchecked") // safe, we just checked
		final var castVersion = (SingularPersistentAttribute<J, Y>) versionAttribute;
		return castVersion;
	}

	private void checkDeclaredVersion() {
		if ( versionAttribute == null || supertypeDeclaresVersion() ) {
			throw new IllegalArgumentException(
					"The version attribute is not declared by this type [" + getJavaType() + "]"
			);
		}
	}

	private boolean supertypeDeclaresVersion() {
		final var superType = getSuperType();
		return superType != null && superType.hasVersionAttribute();
	}

//	@Override
//	public void visitJdbcTypes(Consumer action, TypeConfiguration typeConfiguration) {
//		id.visitJdbcTypes( action, typeConfiguration );
//
//		if ( versionAttribute != null ) {
//			versionAttribute.visitJdbcTypes( action, typeConfiguration );
//		}
//

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use getVersion(Class) — it accepts inherited version attributes
  2. Guard with hasVersionAttribute() plus knowledge that the version may be inherited; or move @Version onto the concrete class if declared semantics matter
  3. Prefer findVersionAttribute() for nullable, hierarchy-aware lookup

Example fix

// before
var v = subtypeType.getDeclaredVersion(Long.class); // @Version on AbstractEntity -> throws

// after
var v = subtypeType.getVersion(Long.class);
Defensive patterns

Strategy: validation

Validate before calling

// Use hierarchy-aware getVersion(); declared-only if you must ensure 'own' declaration
var v = identifiableType.getVersion(javaType); // inherited ok
// or: var v = identifiableType.findVersionAttribute(); // nullable

Try / catch

try {
    return type.getDeclaredVersion(cls);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("version attribute is not declared by this type")) {
        return type.getVersion(cls); // inherited version
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getDeclaredVersion(...) on an entity whose @Version lives in a @MappedSuperclass (typical AbstractEntity base with @Version); calling it on a subtype of a versioned root entity in an inheritance hierarchy.

Common situations: Base-entity templates that centralize @Version in a shared superclass. Generic frameworks calling the declared variant to find 'own' fields.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/500e30fd82330f99. Report an issue: GitHub.