{"record":{"id":"c56ebe716aa6767d","repo":"quarkusio/quarkus","slug":"multiple-additionalpersistenceunitbuilditem-for","errorCode":null,"errorMessage":"Multiple ${AdditionalPersistenceUnitBuildItem} for persistence unit '${puName}'","messagePattern":"Multiple (.+?) for persistence unit '(.+?)'","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/component/PersistenceUnitDefinitionSupport.java","lineNumber":169,"sourceCode":"\n        // Note:\n        // * We do this after deciding whether there should be a default PU on purpose:\n        //   we don't want that decision to be affected by AdditionalPersistenceUnitBuildItem.\n        // * We are guaranteed at this point that no application-configured PU conflicts:\n        //   see checks that prevent using AdditionalPersistenceUnitBuildItem and Quarkus config for the same PU\n        //   in HibernateOrmProcessor.\n        Map<String, PersistenceUnitDefinitionBuildItem.AdditionalConfig> additionalConfigs = new HashMap<>();\n        for (AdditionalPersistenceUnitBuildItem item : additionalPersistenceUnits) {\n            String puName = item.getPersistenceUnitName();\n            puNamesBlockingOrReactive.add(puName);\n            puNamesWithReasons.computeIfAbsent(puName, k -> new ArrayList<>())\n                    .add(item.getReason());\n            var previous = additionalConfigs.put(puName,\n                    new PersistenceUnitDefinitionBuildItem.AdditionalConfig(\n                            item.getDataSourceName(),\n                            item.getExplicitDialect(), item.getProperties()));\n            if (previous != null) {\n                throw new IllegalStateException(\"Multiple \" + AdditionalPersistenceUnitBuildItem.class.getSimpleName()\n                        + \" for persistence unit '\" + puName + \"'\");\n            }\n        }\n\n        if (LOG.isDebugEnabled()) {\n            LOG.debugf(\"Defining %s persistence units; reasons:\\n%s\", paradigm,\n                    puNamesWithReasons.entrySet().stream()\n                            .map(e -> e.getKey() + \": \" + Reason.format(e.getValue()))\n                            .collect(Collectors.joining(\"\\n\")));\n        }\n        for (var entry : puNamesWithReasons.entrySet()) {\n            String puName = entry.getKey();\n\n            List<Reason> unavailableReasons = lookupBuildItem.getLookup().unavailableReasons(puName, paradigm);\n            if (!unavailableReasons.isEmpty()) {\n                throw new ConfigurationException(String.format(Locale.ROOT,\n                        \"\"\"\n                                Hibernate %s persistence unit '%s' cannot be created for the following reason(s):","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/component/PersistenceUnitDefinitionSupport.java#L151-L187","documentation":"PersistenceUnitDefinitionSupport aggregates AdditionalPersistenceUnitBuildItem entries during persistence unit definition. Each additional build item supplies extra config (datasource, dialect, properties) keyed by persistence unit name; if two such items target the same PU name, the second detection throws IllegalStateException because the config would be ambiguous.","triggerScenarios":"Two extensions or configuration sources each produce an AdditionalPersistenceUnitBuildItem for the same persistence unit name while definePersistenceUnits processes them.","commonSituations":"Having both quarkus.hibernate-orm datasource/dialect config and another ORM paradigm (e.g. reactive) extension contributing config for the same PU; duplicate extension config blocks; user-defined build steps emitting a duplicate item.","solutions":["Remove the duplicate AdditionalPersistenceUnitBuildItem contribution — keep one source of config per persistence unit","Check for conflicting config between standard and reactive Hibernate ORM extensions for the same PU","If you write custom build steps, guard against emitting an item when one already exists for the PU name"],"exampleFix":"// before (duplicate contributions for 'pu1' from two extensions)\nquarkus.hibernate-orm.\"pu1\".datasource=ds1\nquarkus.hibernate-reactive.\"pu1\".datasource=ds2\n// after (use only one paradigm per PU)\nquarkus.hibernate-orm.\"pu1\".datasource=ds1","handlingStrategy":"validation","validationCode":"// Keep one paradigm/config source per persistence unit\nMap<String,String> owners = new HashMap<>();\nvoid contribute(String pu, String source) {\n    if (owners.putIfAbsent(pu, source) != null)\n        throw new IllegalStateException(\"PU \" + pu + \" already configured by \" + owners.get(pu));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only one of quarkus.hibernate-orm / quarkus.hibernate-reactive per persistence unit","Avoid duplicate config blocks for the same PU name across application profiles","If writing build steps, check for existing AdditionalPersistenceUnitBuildItem for the PU"],"tags":["quarkus","hibernate-orm","persistence-unit","duplicate-config"],"backgroundTag":"duplicate-configuration-conflict","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}