Reproduce issue with @WithUnnamedKey config group considered present even if unconfigured#1534
Conversation
|
This behavior is expected with the current implementation (not saying it's right or wrong). Consider: @ConfigMapping(prefix = "mapping")
interfaceMapping {
Group group();
@WithDefaults
Map<String, Group> map();
interface Group {
@WithDefault("value")
String value();
}What the implementation does is to generate properties with the values and add them to our mapping.group.value=value
mapping.*.value=valueThe whole idea was to also be able to use the programmatic API to query for the name, so that the values you get from the mapping and the programmatic API are consistent. When you add Should the Because we never required that distinction, everything we populate comes from sources, including defaults, so for the engine, it is just as if someone set We may require a concept that doesn't exist today: distinguishing defaults-only groups from user-configured ones. I'm looking into this from a standalone group perspective, because that was the motivation for us to implement |
Makes sense, but as discussed on Zulip, you only get consistency for the unnamed key -- for other "named" keys, if they are absent from the user's configuration, you won't get any defaults through the programmatic API. That being said, in my case I truly don't need programmatic retrieval to be consistent in any way when it comes to unnamed key -- in fact, if I currently relied on it, we'd have bugs because we don't get consistency for other "named" keys.
IMO, no. If it's not configured, it should not appear in the map keys.
Right, exactly.
So, first, I want to stress I truly don't need this. I just need the map keys to behave 😁 But, if you want a hollistic approach and not a surgical fix... And whatever the solution, IMO it's also fine to not have defaults available for that optional group when retrieving values programmatically. It's a very reasonsable limitation tied to a very specific feature. |
Actually, this does work for the programmatic API :)
Ok, let me see what I can do. |
|
Check if this works for you. The proposal is just to compare the unnamed group with a default group and omit the key in that case (all mappings include equals). Now, if the user explicitly sets a key, but it is a default, the unnamed key won't be included. Is this acceptable? |
yrodiere
left a comment
There was a problem hiding this comment.
That looks perfect! Thank you.
|
Er... maybe I talked too fast. So now, if the user configured the unnamed key by setting a property to its default value, we will omit it from the map? |
Yes. But does that matter? |
Kind of, yes. The idea is to use configuration to extract a list of datasources (or persistence units, or...) that the user explicitly configured, because we know those need to be created for sure (unless they're explicitly disabled). Before this patch, I was in trouble because the map could contain In practice this is just one datapoint, and I'll try to also inspect injection points and other things. But still, it does mean we'll have a hole in our detection code... |
|
I did it this way because it was an easy fix that didn't require messing with the names or the defaults, which I wanted to avoid. Let me think about this again. |
d301c73 to
d95824a
Compare
|
Ok, give it another try. |
d95824a to
0b04a3c
Compare
…sio#1534 Remove the isAnyPropertySet()/isDefault() workarounds that skip the default entry from config map keySet(). These workarounds existed because @WithUnnamedKey caused the default key to always appear in keySet(), even with no user configuration. With SmallRye Config PR quarkusio#1534 (smallrye/smallrye-config#1534), the default key will only appear when the user explicitly sets a property for it, making keySet() trustworthy. This commit is expected to cause test failures until the SmallRye Config upgrade lands.
…dKey fix Testing commit for smallrye/smallrye-config#1534. To reproduce: ``` ./mvnw verify -f extensions/agroal/deployment/ -Dtest-containers -Dstart-containers \ -Dtest="NamedDataSourceConfigTest#testDefaultDataSourceNotCreated" \ -Dquarkus.log.category.\"io.quarkus.datasource.deployment\".level=DEBUG ``` NamedDataSourceConfigTst#testDefaultDataSourceNotCreated still fails. See in particular the logs: ``` 2026-06-23 13:26:56,214 DEBUG [io.quarkus.datasource.deployment.DataSourceProcessorUtil] (build-2) Collecting implicit BLOCKING datasource requests from configuration '*': keySet = [<default>] 2026-06-23 13:26:56,220 DEBUG [io.quarkus.datasource.deployment.DataSourceProcessorUtil] (build-2) Collecting implicit BLOCKING datasource requests from configuration 'jdbc.*': keySet = [testing] 2026-06-23 13:26:56,404 DEBUG [io.quarkus.datasource.deployment.DataSourceProcessorUtil] (build-5) Defining BLOCKING datasources; reasons: <default>: - Configuration 'quarkus.datasource.*' testing: - Configuration 'quarkus.datasource."testing".jdbc.*' - Injection of 'AgroalDataSource' at: io.quarkus.agroal.test.NamedDataSourceConfigTest#ds ``` Interestingly, this tells us the default datasource is present in the keyset of `io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig#dataSources` but not in the keyset of `io.quarkus.agroal.runtime.DataSourcesJdbcBuildTimeConfig#dataSources`.
…sio#1534 Remove the isAnyPropertySet()/isDefault() workarounds that skip the default entry from config map keySet(). These workarounds existed because @WithUnnamedKey caused the default key to always appear in keySet(), even with no user configuration. With SmallRye Config PR quarkusio#1534 (smallrye/smallrye-config#1534), the default key will only appear when the user explicitly sets a property for it, making keySet() trustworthy. This commit is expected to cause test failures until the SmallRye Config upgrade lands.
…dKey fix Testing commit for smallrye/smallrye-config#1534. To reproduce: ``` ./mvnw verify -f extensions/agroal/deployment/ -Dtest-containers -Dstart-containers \ -Dtest="NamedDataSourceConfigTest#testDefaultDataSourceNotCreated" \ -Dquarkus.log.category.\"io.quarkus.datasource.deployment\".level=DEBUG ``` NamedDataSourceConfigTst#testDefaultDataSourceNotCreated still fails. See in particular the logs: ``` 2026-06-23 13:26:56,214 DEBUG [io.quarkus.datasource.deployment.DataSourceProcessorUtil] (build-2) Collecting implicit BLOCKING datasource requests from configuration '*': keySet = [<default>] 2026-06-23 13:26:56,220 DEBUG [io.quarkus.datasource.deployment.DataSourceProcessorUtil] (build-2) Collecting implicit BLOCKING datasource requests from configuration 'jdbc.*': keySet = [testing] 2026-06-23 13:26:56,404 DEBUG [io.quarkus.datasource.deployment.DataSourceProcessorUtil] (build-5) Defining BLOCKING datasources; reasons: <default>: - Configuration 'quarkus.datasource.*' testing: - Configuration 'quarkus.datasource."testing".jdbc.*' - Injection of 'AgroalDataSource' at: io.quarkus.agroal.test.NamedDataSourceConfigTest#ds ``` Interestingly, this tells us the default datasource is present in the keyset of `io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig#dataSources` but not in the keyset of `io.quarkus.agroal.runtime.DataSourcesJdbcBuildTimeConfig#dataSources`.
0b04a3c to
ca6c2ad
Compare
Parameterized tests documenting current behavior of @WithDefaults and @WithUnnamedKey on Maps in @ConfigMapping interfaces. Assertions expect correct behavior; 6 tests currently fail, documenting a bug where the unnamed config group key materializes when the config group has a config property with @WithDefault, even when nothing is configured. Assisted-By: Claude Code <noreply@anthropic.com>
ca6c2ad to
5432b1b
Compare
…ue is the default
5432b1b to
d6e952f
Compare
|
Thank you! |
Creating for discussion following https://quarkusio.zulipchat.com/#narrow/channel/187038-dev/topic/.40WithUnnamedKey.20and.20keySet/with/603369236
Running the tests and reading the "ISSUE" comments is probably is the easiest way to grasp what is going on.
Test results: