matrei opened a new issue, #16455:
URL: https://github.com/apache/grails-core/issues/16455

   With `grails-data-hibernate7`, an application without a `dataSource` block 
in its configuration gets no `dataSource`
   bean, and no `DataSource` bean at all. GORM still creates and uses a default 
datasource (H2,
   `jdbc:h2:mem:grailsDB;LOCK_TIMEOUT=10000`, from `DataSourceSettings`' 
defaults), and domain classes work, but the
   datasource is only reachable through 
`hibernateDatastore.connectionSources.defaultConnectionSource.dataSource`.
   
   Adding any `dataSource` block makes the bean appear, even one that only 
repeats a default:
   
   ```yaml
   dataSource:
       dbCreate: none
   ```
   
   So whether the default datasource is exposed as a bean depends on whether 
the config has a `dataSource` block, not on
   its contents.
   
   Related: #14356 (registering the `dataSource` bean early enough for Spring 
Boot auto-configuration).
   
   ### Cause
   
   
`grails.orm.bootstrap.HibernateDatastoreSpringInitializer#configureDataSources` 
(`grails-data-hibernate7`) collects the
   datasource names from the config, and only adds the default when the 
`dataSource` map is non-empty:
   
   ```groovy
   if (config == null) {
       dataSourceNames = [defaultDataSourceBeanName] as Set
   }
   else {
       Map dataSources = config.getProperty(DATA_SOURCES, Map, 
Collections.emptyMap())
       if (dataSources != null && !dataSources.isEmpty()) {
           
dataSourceNames.addAll(AbstractConnectionSources.toValidConnectionSourceNames(dataSources))
       }
       Map dataSource = (Map) config.getProperty(DEFAULT_DATA_SOURCE_NAME, Map, 
Collections.emptyMap())
       if (dataSource != null && !dataSource.isEmpty()) {
           dataSourceNames.add(ConnectionSource.DEFAULT)
       }
   }
   ```
   
   `HibernateDatastoreConnectionSourcesRegistrar` then registers a `dataSource` 
bean only for the names in that set, so
   with no `dataSource` config the set is empty and no bean is registered. The 
initializer itself skips the default
   (`if (dataSourceName == ConnectionSource.DEFAULT) continue`), and 
`DataSourceGrailsPlugin` (`grails-datasource`)
   doesn't register one either when the Hibernate plugin is present (`if 
(pluginManager.hasGrailsPlugin('hibernate'))`).
   
   The `config == null` branch shows the default is meant to be included. A 
config without a `dataSource` block falls
   through to the `else` branch and loses it, although `HibernateDatastore` 
creates the default connection source
   regardless.
   
   ### Expected Behavior
   
   The default datasource that GORM creates and uses is always available as the 
`dataSource` bean (and as a `DataSource`
   for by-type injection), whether or not the application configures a 
`dataSource` block. That's consistent with how a
   `dataSource` block that only repeats defaults behaves.
   
   ### Actual Behaviour
   
   With no `dataSource` configuration, 
`applicationContext.getBeansOfType(DataSource)` is empty and
   `getBean('dataSource')` fails with `NoSuchBeanDefinitionException: No bean 
named 'dataSource' available`. Anything
   that injects the datasource by name or type cannot be created, although the 
application has a working default
   datasource.
   
   ### Steps To Reproduce
   
   1. Create a Grails 8.0.0-RC2 application with `grails-data-hibernate7`, H2 
and HikariCP, a domain class, and no
      `dataSource` block in `application.yml`.
   2. In `BootStrap`, print 
`grailsApplication.mainContext.getBeansOfType(javax.sql.DataSource).keySet()`: 
`[]`.
   3. Print 
`hibernateDatastore.connectionSources.defaultConnectionSource.dataSource`: a 
working `HikariDataSource` for
      `jdbc:h2:mem:grailsDB;LOCK_TIMEOUT=10000`.
   4. Add `dataSource: { dbCreate: none }` (equal to the default) to 
`application.yml` and repeat: `[dataSource]`, backed
      by the same `HikariDataSource`.
   
   ### Suggested Fix
   
   Always include the default connection source name in `configureDataSources`, 
as the `config == null` branch already
   does, since `HibernateDatastore` always creates the default connection 
source. For example, start with
   `dataSourceNames = [ConnectionSource.DEFAULT] as Set` in both branches. If 
the absence of the bean is intended,
   document that applications must configure a `dataSource` block to get it.
   
   ### Environment Information
   
   - Grails 8.0.0-RC2 (`grails-data-hibernate7`, `grails-datasource` 8.0.0-RC2)
   - H2 2.4.240, HikariCP 7.0.2
   - JDK 21
   
   ### Example Application
   
   _No response_
   
   ### Version
   
   8.0.0-RC2
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to