{"record":{"id":"bf79269fe39fa9d5","repo":"hibernate/hibernate-orm","slug":"attributeconverter-class-s-registered-multiple","errorCode":null,"errorMessage":"AttributeConverter class [%s] registered multiple times","messagePattern":"AttributeConverter class \\[(.+?)\\] registered multiple times","errorType":"exception","errorClass":"AssertionFailure","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java","lineNumber":288,"sourceCode":"\n\t@Override\n\tpublic ManagedTypeRepresentationResolver getRepresentationStrategySelector() {\n\t\treturn representationStrategySelector;\n\t}\n\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// Mutations\n\n\tpublic void addAttributeConverterDescriptor(ConverterDescriptor<?,?> descriptor) {\n\t\tif ( attributeConverterDescriptorMap == null ) {\n\t\t\tattributeConverterDescriptorMap = new HashMap<>();\n\t\t}\n\n\t\tfinal var attributeConverterClass = descriptor.getAttributeConverterClass();\n\t\tfinal Object old = attributeConverterDescriptorMap.put( attributeConverterClass, descriptor );\n\t\tif ( old != null ) {\n\t\t\tthrow new AssertionFailure(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\"AttributeConverter class [%s] registered multiple times\",\n\t\t\t\t\t\t\tattributeConverterClass\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\tvoid injectJpaTempClassLoader(ClassLoader classLoader) {\n\t\tif ( BOOT_LOGGER.isTraceEnabled() && classLoader != getJpaTempClassLoader() ) {\n\t\t\tBOOT_LOGGER.injectingJpaTempClassLoader( classLoader, getJpaTempClassLoader() );\n\t\t}\n\t\tthis.classLoaderAccess.injectTempClassLoader( classLoader );\n\t}\n\n\tpublic void injectScanning(ScanningProvider scanningProvider) {\n\t\tif ( scanningProvider != this.scanningSetting ) {\n\t\t\tBOOT_LOGGER.injectingScanner( scanningProvider, this.scanningSetting );","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java#L270-L306","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Search persistence.xml and all bootstrap code for the converter class named in the message and remove the duplicate registration","If registering programmatically, funnel registrations through a single guarded point that skips already-registered classes","When converter scanning is enabled, remove the manual registration of scanned converters","Do a clean redeploy to rule out stale descriptors from a previous deployment"],"exampleFix":"// before: registered twice (persistence.xml <converter class=\"com.acme.MyConverter\"/> AND code)\nbuilder.applyAttributeConverter(new MyConverter());\n\n// after: keep exactly one registration - remove the persistence.xml <converter> entry\nbuilder.applyAttributeConverter(new MyConverter());","handlingStrategy":"validation","validationCode":"// Deduplicate converter registrations before bootstrapping\nSet<Class<?>> registered = new HashSet<>();\nfor (ConverterDescriptor d : descriptors) {\n    if (!registered.add(d.getAttributeConverterClass())) {\n        continue; // same class already registered - skip instead of throwing AssertionFailure\n    }\n    builder.applyAttributeConverter(d);\n}","typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = metadata.buildSessionFactory();\n}\ncatch (AssertionFailure e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"registered multiple times\")) {\n        // locate the duplicate AttributeConverter registration and remove one path\n    }\n    throw e;\n}","preventionTips":["Grep persistence.xml for duplicate <converter class=...> entries before release","Use one registration point for converters (scanning OR explicit), never both"],"tags":["hibernate","jpa","attribute-converter","bootstrap"],"backgroundTag":"duplicate-converter-registration","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}