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

  1. Clean the build outputs (delete classes/build dirs, invalidate CI cache) so enhancement runs on never-enhanced classes compiled fresh.
  2. Align Hibernate versions across all modules/plugins so the enhancing version matches what produced the classes.
  3. Stop re-enhancing already-enhanced artifacts - consume them as-is or rebuild them from source with the current version.
  4. 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

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


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