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.