hibernate/hibernate-orm · error · AssertionFailure

AttributeConverter class [%s] registered multiple times

Error message

AttributeConverter class [%s] registered multiple times

What it means

BootstrapContextImpl.addAttributeConverterDescriptor stores ConverterDescriptors in a map keyed by converter class and asserts that no entry existed before. If registering a converter class a second time (put returns a non-null old value), Hibernate throws AssertionFailure with the class name: each AttributeConverter class may be registered exactly once per bootstrap.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java:288

	@Override
	public ManagedTypeRepresentationResolver getRepresentationStrategySelector() {
		return representationStrategySelector;
	}


	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Mutations

	public void addAttributeConverterDescriptor(ConverterDescriptor<?,?> descriptor) {
		if ( attributeConverterDescriptorMap == null ) {
			attributeConverterDescriptorMap = new HashMap<>();
		}

		final var attributeConverterClass = descriptor.getAttributeConverterClass();
		final Object old = attributeConverterDescriptorMap.put( attributeConverterClass, descriptor );
		if ( old != null ) {
			throw new AssertionFailure(
					String.format(
							"AttributeConverter class [%s] registered multiple times",
							attributeConverterClass
					)
			);
		}
	}

	void injectJpaTempClassLoader(ClassLoader classLoader) {
		if ( BOOT_LOGGER.isTraceEnabled() && classLoader != getJpaTempClassLoader() ) {
			BOOT_LOGGER.injectingJpaTempClassLoader( classLoader, getJpaTempClassLoader() );
		}
		this.classLoaderAccess.injectTempClassLoader( classLoader );
	}

	public void injectScanning(ScanningProvider scanningProvider) {
		if ( scanningProvider != this.scanningSetting ) {
			BOOT_LOGGER.injectingScanner( scanningProvider, this.scanningSetting );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Search persistence.xml and all bootstrap code for the converter class named in the message and remove the duplicate registration
  2. If registering programmatically, funnel registrations through a single guarded point that skips already-registered classes
  3. When converter scanning is enabled, remove the manual registration of scanned converters
  4. Do a clean redeploy to rule out stale descriptors from a previous deployment

Example fix

// before: registered twice (persistence.xml <converter class="com.acme.MyConverter"/> AND code)
builder.applyAttributeConverter(new MyConverter());

// after: keep exactly one registration - remove the persistence.xml <converter> entry
builder.applyAttributeConverter(new MyConverter());
Defensive patterns

Strategy: validation

Validate before calling

// Deduplicate converter registrations before bootstrapping
Set<Class<?>> registered = new HashSet<>();
for (ConverterDescriptor d : descriptors) {
    if (!registered.add(d.getAttributeConverterClass())) {
        continue; // same class already registered - skip instead of throwing AssertionFailure
    }
    builder.applyAttributeConverter(d);
}

Try / catch

try {
    sessionFactory = metadata.buildSessionFactory();
}
catch (AssertionFailure e) {
    if (e.getMessage() != null && e.getMessage().contains("registered multiple times")) {
        // locate the duplicate AttributeConverter registration and remove one path
    }
    throw e;
}

Prevention

When it happens

Trigger: The same converter class reaches addAttributeConverterDescriptor through two registration paths: listed twice in persistence.xml <converter class=...>, added twice programmatically via MetadataBuilder.applyAttributeConverter, or auto-discovered (autoApply/@Converter with autoApply, container scanning) plus an explicit manual registration.

Common situations: Duplicate <converter> entries in persistence.xml; a shared library and the application both registering the same converter; Spring Boot scanning converters that are also added by hand; stale deployment descriptors in app servers after refactoring.

Related errors


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