hibernate/hibernate-orm · error · VersionMismatchException
Mismatch between Hibernate version used for bytecode enhance
Error message
Mismatch between Hibernate version used for bytecode enhancement (%s) and runtime (%s) for `%s`
What it means
When the enhancer encounters a class that already carries Hibernate enhancement instrumentation, verifyReEnhancement() compares the version string stamped into the existing EnhancementInfo against Version.getVersionString() of the running Hibernate. Any difference (except the literal 'ignore', reserved for tests and logged via skippingReEnhancementVersionCheck) throws VersionMismatchException - re-enhancing instrumented bytes from another Hibernate release is unsupported because the internal contract may have changed.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/EnhancerImpl.java:517
.to( CodeTemplates.ClearDirtyCollectionNames.class, constants.adviceLocator )
.wrap( StubMethod.INSTANCE ) )
.defineMethod( REMOVE_DIRTY_FIELDS_NAME, constants.TypeVoid, constants.modifierPUBLIC )
.withParameter( constants.TypeLazyAttributeLoadingInterceptor )
.intercept( clearDirtyNames );
}
private void verifyReEnhancement(
TypeDescription managedCtClass,
EnhancementInfo existingInfo,
ByteBuddyEnhancementContext enhancementContext) {
// first, make sure versions match
final String enhancementVersion = existingInfo.version();
if ( "ignore".equals( enhancementVersion ) ) {
// for testing
ENHANCEMENT_LOGGER.skippingReEnhancementVersionCheck( managedCtClass.getName() );
}
else if ( !Version.getVersionString().equals( enhancementVersion ) ) {
throw new VersionMismatchException( managedCtClass, enhancementVersion,
Version.getVersionString() );
}
FeatureMismatchException.checkFeatureEnablement(
managedCtClass,
DIRTY_CHECK,
enhancementContext.doDirtyCheckingInline(),
existingInfo.includesDirtyChecking()
);
FeatureMismatchException.checkFeatureEnablement(
managedCtClass,
ASSOCIATION_MANAGEMENT,
enhancementContext.doBiDirectionalAssociationManagement(),
existingInfo.includesAssociationManagement()
);
}
View on GitHub (pinned to fad1729dce)
Solutions
- Clean the build outputs (delete classes/build dirs, invalidate CI cache) so enhancement runs on never-enhanced classes compiled fresh.
- Align Hibernate versions across all modules/plugins so the enhancing version matches what produced the classes.
- Stop re-enhancing already-enhanced artifacts - consume them as-is or rebuild them from source with the current version.
- Test-only: stamp the existing enhancement info version as 'ignore' to bypass the check (it will log skippingReEnhancementVersionCheck); never ship that.
Example fix
# before ./gradlew compileJava # incremental: keeps classes enhanced by hibernate 6.6, now using 7.0 # -> VersionMismatchException(enhancementVersion=6.6.x, runtime=7.0.x) # after ./gradlew clean compileJava # enhance from pristine, never-enhanced classes
Defensive patterns
Strategy: fallback
Validate before calling
// skip re-enhancement of classes already enhanced by another version before calling the enhancer
static boolean needsEnhancement(String className, byte[] bytes, String currentVersion) {
return !classNameContainsEnhancementMarker( bytes ) // e.g. Managed interface in constant pool
|| readsEnhancementVersion( bytes ).equals( currentVersion );
} Try / catch
try { enhanced = enhancer.enhance( className, bytes ); }
catch ( VersionMismatchException e ) {
// classes were enhanced by a different Hibernate: rebuild from pristine sources
cleanOutputsAndRebuild( className ); // then enhance the freshly compiled bytes once
} Prevention
- Always clean builds (or bust incremental/CI caches) after changing the hibernate-core version.
- Never feed already-enhanced artifacts back into enhancement; enhance once, from source, per version.
- Fail the build with a clear message when a VersionMismatchException is seen in CI rather than retrying it.
When it happens
Trigger: Enhancement running over classes that were already enhanced by a different Hibernate version: stale build outputs after a Hibernate upgrade, a fat jar containing pre-enhanced classes reused as compilation input, or CI caches retaining enhanced classes from the previous dependency version.
Common situations: Bumping hibernate-core (e.g. 6.6 -> 7.0) without cleaning build/incremental caches; multi-module builds where an upstream artifact ships enhanced classes and the downstream re-enhances them; IDE incremental compilation keeping old instrumented classes.
Related errors
- Failed to enhance class {className}
- Failed to discover types for class {className}
- Support for %s was enabled during enhancement, but `%s` was
- Could not locate method needed for ValidatorFactory validati
- Unable to locate TypeSafeActivator#activate method
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/6fa04d3186e024b7.
Report an issue: GitHub.