jamesfredley opened a new issue, #16567:
URL: https://github.com/apache/grails-core/issues/16567
## Summary
`dataSource.properties.maximumPoolSize` in `application.yml` does not reach
HikariCP on Grails 8.0.0. The application connects with the URL, username, and
password from the same `dataSource` block, and the live pool stays at Hikari's
default of 10.
This is not issue #15501. That issue, fixed by #15502 (`71578fd6b5`, James
Daugherty, in `v8.0.0`), flattens nested `dbProperties` /
`dataSourceProperties` once they are already inside the map passed to
`DataSourceBuilder`. `DataSourceBuilderSpec` proves
`builder.properties([maximumPoolSize: '20'])` binds. The
YAML-to-`DataSourceSettings.properties` step never produces that map.
## What I ran
Grails 8.0.0, `grails-datamapping-core-8.0.0.jar`, Hibernate 7, PostgreSQL.
`grails-app/conf/application.yml`:
```yaml
environments:
loadtest:
dataSource:
url: jdbc:postgresql://localhost:5438/chirp_optimized?tcpKeepAlive=true
username: chirp
password: chirp
pooled: true
type: com.zaxxer.hikari.HikariDataSource
properties:
maximumPoolSize: 16
minimumIdle: 8
connectionTimeout: 2000
```
The same block is also in `application-loadtest.yml`
(`spring.config.activate.on-profile: loadtest`), and that file aliases it onto
`environments.loadtest`.
Launch:
```text
java -Dgrails.env=loadtest -jar app.war --spring.profiles.active=loadtest
```
The process came up on the loadtest port, as user `chirp`, against
`chirp_optimized`. Those values exist only in the loadtest block, so that
environment was the one that ran.
After startup:
```sql
SELECT datname, count(*) FROM pg_stat_activity WHERE datname =
'chirp_optimized' GROUP BY datname;
```
Result: 10 connections. That is Hikari's default `maximumPoolSize`.
`minimumIdle: 8` would have left 8 idle connections. The startup log also
reports `HikariPool-1` and Hibernate's "Maximum pool size: undefined/unknown".
## Where it drops
`DataSourceSettings` is a `@Builder(builderStrategy = SimpleStrategy, prefix
= '')` type with `Map properties = [:]`. `ConfigurationBuilder` fills a
Map-typed builder method from:
```groovy
propertyResolver.getProperty("dataSource.properties", Map,
Collections.emptyMap())
```
(`ConfigurationBuilder.groovy` around the `newBuilder instanceof Map`
branch, line 261 on `v8.0.0`.)
Spring's `Environment.getProperty("dataSource.properties", Map)` does not
return the nested YAML map. The keys exist only as
`dataSource.properties.maximumPoolSize`. The map stays empty.
`DataSourceConnectionSourceFactory.create()` then skips the binder:
```java
Map properties = settings.getProperties();
if (properties != null && !properties.isEmpty()) {
dataSourceBuilder.properties(settings.toProperties());
}
```
(`DataSourceConnectionSourceFactory.java` lines 95-99 on `v8.0.0`.)
URL, username, and password are applied on their own, which is why the app
connects and the pool size does not change. #15502 never runs, because
`DataSourceBuilder.properties()` is never called.
`8aee63808c` ("Bind nested settings entries the resolver cannot address by
path") binds a value the caller already holds. It does not assemble dotted YAML
keys into `dataSource.properties` when `getProperty(path, Map)` is empty. The
commit message on `7d5e684929` already notes that a resolver which does not
expose dotted entries can still drop a configured value. Grails'
`DatastoreUtils.createPropertyResolver` flattens, which is why the unit specs
pass. A running app passes Spring's `Environment`, which does not.
## Expected
```yaml
dataSource:
type: com.zaxxer.hikari.HikariDataSource
properties:
maximumPoolSize: 16
minimumIdle: 8
connectionTimeout: 2000
```
should produce a Hikari pool with maximum 16 and minimum idle 8, in the
Grails environment that contains that block.
--
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]