{"record":{"id":"b720c8f3f7eb7864","repo":"hibernate/hibernate-orm","slug":"illegal-value-for-configuration-setting-hibernate","errorCode":null,"errorMessage":"illegal value for configuration setting 'hibernate.connection.datasource'","messagePattern":"illegal value for configuration setting 'hibernate\\.connection\\.datasource'","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"critical","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.java","lineNumber":77,"sourceCode":"\tprotected DataSource selectDataSource(T tenantIdentifier) {\n\t\tDataSource dataSource = dataSourceMap().get( tenantIdentifier );\n\t\tif ( dataSource == null ) {\n\t\t\tdataSource = (DataSource) jndiService.locate( baseJndiNamespace + '/' + tenantIdentifier );\n\t\t\tdataSourceMap().put( tenantIdentifier, dataSource );\n\t\t}\n\t\treturn dataSource;\n\t}\n\n\tprivate Map<T, DataSource> dataSourceMap() {\n\t\treturn dataSourceMap;\n\t}\n\n\t@Override\n\tpublic void injectServices(@Nonnull ServiceRegistryImplementor serviceRegistry) {\n\t\tfinal var configurationService = serviceRegistry.requireService( ConfigurationService.class );\n\t\tfinal Object dataSourceConfigValue = configurationService.getSettings().get( DATASOURCE );\n\t\tif ( !(dataSourceConfigValue instanceof String configuredJndiName) ) {\n\t\t\tthrow new HibernateException( \"illegal value for configuration setting '\" + DATASOURCE + \"'\" );\n\t\t}\n\t\tjndiName = configuredJndiName;\n\n\t\tjndiService = serviceRegistry.getService( JndiService.class );\n\t\tif ( jndiService == null ) {\n\t\t\tthrow new HibernateException( \"Could not locate JndiService from DataSourceBasedMultiTenantConnectionProviderImpl\" );\n\t\t}\n\n\t\tfinal Object namedObject = jndiService.locate( this.jndiName );\n\t\tif ( namedObject == null ) {\n\t\t\tthrow new HibernateException( \"JNDI name [\" + this.jndiName + \"] could not be resolved\" );\n\t\t}\n\t\telse if ( namedObject instanceof DataSource datasource ) {\n\t\t\tfinal int loc = jndiName.lastIndexOf( '/' );\n\t\t\tbaseJndiNamespace = jndiName.substring( 0, loc );\n\t\t\tfinal String prefix = jndiName.substring( loc + 1);\n\t\t\ttenantIdentifierForAny = (T) prefix;\n\t\t\tdataSourceMap().put( tenantIdentifierForAny, datasource );","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.java#L59-L95","documentation":"DataSourceBasedMultiTenantConnectionProviderImpl.injectServices reads the setting hibernate.connection.datasource and requires it to be a String holding a JNDI name, because this provider locates per-tenant DataSources through JNDI. If the value is absent or not a String (e.g. a DataSource instance was placed in the settings map), Hibernate throws HibernateException with this message during ServiceRegistry injection at bootstrap.","triggerScenarios":"Configuring hibernate.multiTenancy with DataSourceBasedMultiTenantConnectionProviderImpl while AvailableSettings.DATASOURCE ('hibernate.connection.datasource') is missing, or is a javax.sql.DataSource object, Integer, or any non-String value in the properties map passed to sessionFactory building.","commonSituations":"Spring Boot or programmatic bootstrap putting a DataSource bean into hibernate properties instead of a JNDI name; copy-pasted persistence.xml where <jta-data-source>/<non-jta-data-source> semantics differ; migrating a working single-tenant JNDI setup where the property was omitted.","solutions":["Set the property to the JNDI name string, e.g. hibernate.connection.datasource=java:/datasources/tenants","If you do not use JNDI, replace this provider with a custom MultiTenantConnectionProvider that maps tenant identifiers to DataSource instances directly","Verify no code overrides the property with a non-String value after configuration merging"],"exampleFix":"// before\nMap<String,Object> settings = new HashMap<>();\nsettings.put(AvailableSettings.DATASOURCE, myDataSourceObject); // not a String -> HibernateException\n\n// after\nsettings.put(AvailableSettings.DATASOURCE, \"java:/datasources/tenants\");","handlingStrategy":"validation","validationCode":"// validate before building the SessionFactory\nObject v = settings.get(AvailableSettings.DATASOURCE);\nif ( providerIsDataSourceBased && !(v instanceof String jndiName) ) {\n    throw new IllegalArgumentException(\n        \"hibernate.connection.datasource must be a JNDI name String, got: \" + v);\n}","typeGuard":null,"tryCatchPattern":"try {\n    sf = builder.build();\n} catch (HibernateException e) {\n    if ( e.getMessage() != null && e.getMessage().contains(\"hibernate.connection.datasource\") ) {\n        throw new ConfigurationException(\"Fix hibernate.connection.datasource to a JNDI name String\", e);\n    }\n    throw e;\n}","preventionTips":["Never put a DataSource object into hibernate.connection.datasource; that setting is JNDI-name-only in Hibernate","Validate all String-typed Hibernate settings in one startup check before EntityManagerFactory creation"],"tags":["hibernate","multitenancy","configuration","jndi","datasource","bootstrap"],"backgroundTag":"invalid-configuration-value","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}