On one hand documentation shows how to configure database with uri https://docs.spring.io/spring-boot/reference/data/nosql.html#data.nosql.mongodb.connecting
as shown in the following example:
spring:
data:
mongodb:
uri: "mongodb://user:secret@mongoserver1.example.com:27017,mongoserver2.example.com:23456/test"
On the other hand property reference denies uri configurability
https://docs.spring.io/spring-boot/appendix/application-properties/index.html#application-properties.data.spring.data.mongodb.port
spring.data.mongodb.port | Mongo server port. Cannot be set with URI. spring.data.mongodb.uri | Mongo database URI. Overrides host, port, username, and password. spring.data.mongodb.database | Database name. Overrides database in URI. spring.data.mongodb.host | Mongo server host. Cannot be set with URI. spring.data.mongodb.password | Login password of the mongo server. Cannot be set with URI. spring.data.mongodb.replica-set-name | Required replica set name for the cluster. Cannot be set with URI.
Unable to understand, basing on documentation, what is allowed in URI and what overrides what
Comment From: nosan
If Mongo database URI spring.data.mongodb.uri property is specified it will be used as ConnectionString
, otherwise ConnectionString
will be built based on other properties such as spring.data.mongodb.host
, etc.
https://github.com/spring-projects/spring-boot/blob/109fd6f97da95ab78d20cbaddb2ca817e647cd1c/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java#L53-L57
The spring.data.mongodb.database
property is an exception, this property has higher precedence over spring.data.mongodb.uri
property.
https://github.com/spring-projects/spring-boot/blob/a8948790854796789a4087739ed7199a43a0300c/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java#L87-L91
https://github.com/spring-projects/spring-boot/blob/593fa1dc42177cc33b076643bd2ba6c66e84a3db/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java#L48-L51
Comment From: michaldo
Thanks for clarification.
In my opinion, any "discrete" property should override value in ConnectionString
/spring.data.mongodb.uri
. That would be simpler, without exception logic. (lex specialis derogat legi generali)
But, if you decided keep current implementation, please fix documentation ("Cannot be set with URI" is false)
Comment From: wilkinsona
In my opinion, any "discrete" property should override value in ConnectionString/spring.data.mongodb.uri. That would be simpler
We cannot do that as there are many users relying on the current behavior.
"Cannot be set with URI" is false
It isn't false, but it is perhaps unclearly worded. What it means is that it cannot be set in combination with the URI property as it will then be overridden. We can use this issue to clarify things.
Comment From: michaldo
We cannot do that as there are many users relying on the current behavior.
Current behavior is spring.data.mongodb.uri
overrides spring.data.mongodb.host
. Could you explain use case for that?
For example, I can explain use case for spring.data.mongodb.database
overriding spring.data.mongodb.uri
:
I can define global mongo URI for 10 services and update only database
fragment in each service.
But use case for unused host
fragment overriden by whole uri
- I don't think so.
I'm aware that changing implementation is breaking. It would be good enough for now to clarify documentation reference. For long term, you should consider breaking change to implementation that fragment overrides whole - it is IMHO more logical than current implementation when one fragment out of many overrides whole but others not
Comment From: wilkinsona
Users configure separate properties (host, port, etc) for one environment and want to be able to override all of the configuration by setting a single property. This is often useful when migrating through deployment environments where the settings come from different sources. For example, some Mongo SaaS providers only make the configuration available as a single value.
For long term, you should consider breaking change to implementation that fragment overrides whole - it is IMHO more logical than current implementation when one fragment out of many overrides whole but others not
Which is better or more logical is subjective and I don't think we can justify changing it without a very strong reason to do so.
Closing in favor of #44384. Thanks for the PR, @nosan.
Comment From: michaldo
Thanks for use case example.
JDBC connection setup is much simpler - just 3 properties: url, username and password.
I think now that if JDBC can live without spring.datasource.host
, spring.datasource.port
, etc., the same pattern should be used by Mongo. I mean there should be only one property: spring.data.mongodb.uri
. No exceptions, no overriding doubts.