Hi,
spring boot auto configures two MongoDB clients, one through MongoAutoConfiguration and one through MongoReactiveAutoConfiguration. If I try to exclude MongoAutoConfiguration I get the following error:
````
APPLICATION FAILED TO START
Description:
Parameter 0 of method mongoDbFactory in org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration required a bean of type 'com.mongodb.MongoClient' that could not be found.
- Bean method 'mongo' not loaded because auto-configuration 'MongoAutoConfiguration' was excluded
````
Then, If I try to exclude MongoDataAutoConfiguration as well I get the following error:
````
APPLICATION FAILED TO START
Description:
Parameter 1 of method reactiveMongoTemplate in org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration required a bean of type 'org.springframework.data.mongodb.core.convert.MongoConverter' that could not be found.
- Bean method 'mappingMongoConverter' not loaded because auto-configuration 'MongoDataAutoConfiguration' was excluded
````
Looks that is not possible to exclude the non reactive part.
Below you can find a simple example where "Cluster created with settings....etc" is logged two times:
https://github.com/cmario/spring-boot-embedded-mongodb
Regards
Mario
Is this causing you a problem beyond the logging that you've noticed? The two clients that are auto-configured are not the same. One is an instance of com.mongodb.reactivestreams.client.MongoClient and the other is an instance of com.mongodb.MongoClient.
Actually I had a weird behaviour in my application. Is totally random and happened to me 2/3 times that a RESTFul endpoint with just one query to MongoDB, it just stuck. The connection time and the socket time as per the connection string wasn't respected, no errors and no logs. The connection pool was looking fine because I was able to see in the logs that the idle connections were closed and reopened. Restarting mongodb itself didn't help, I had to restart the application itself.
That is the reason I started to look into it and I realized the two mongodb clients were created. Of course I'm not sure that the two things are related and I know that we are talking about two different clients, but you know, less stuff you have less stuff can be broken :-).
Unfortunately is quite random and not easy do debug. I put in debug mode the mongodb package, at least I hope to see something next time that happens. I will update you.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
I wasn't able to reproduce the issue. Remains the fact that two client instances (with related connection pool etc..) shouldn't be created, is a waste of resources. Therefore, in my opinion, this issue should be reopened.
When we fix this we should also add a class condition for reactor on MongoReactiveDataAutoConfiguration.
We need to make MongoDataAutoConfiguration back off if MongoAutoConfiguration has been excluded.
I can't quite recall what we discussed on the call. If we make MongoDataAutoConfiguration back off, that would cause MongoReactiveDataAutoConfiguration to fail because there would be no MongoConverter bean. I thought MongoDataAutoConfiguration and MongoReactiveDataAutoConfiguration would be completely independent but it looks like that is not the case.
I thought
MongoDataAutoConfigurationandMongoReactiveDataAutoConfigurationwould be completely independent
I thought they would be too. Sounds like we need to fix that.
Perhaps we could move the configuration of the MongoConverter and other beans that it depends upon into a separate configuration class that could be imported by both MongoDataAutoConfiguration and MongoReactiveDataAutoConfiguration?
@mp911de Do you have any suggestions on how we can achieve a clean separation between the MongoReactiveDataAutoConfiguration and MongoDataAutoConfiguration? Currently, the MongoReactiveDataAutoConfiguration creates a ReactiveMongoTemplate bean which relies on the MappingMongoConverter from MongoDataAutoConfiguration. This seems a bit odd as the MappingMongoConverter is set up with SimpleMongoDbFactory which uses a blocking MongoClient.
Imperative and reactive bits in Spring Data Mongo are not entirely independent of each other. We require currently some infrastructure parts which require also the blocking driver to be present.
We need to investigate how to decouple the infrastructure from the actual driver.
Thanks @mp911de. I've created an issue here for the investigation.
Decoupling is possible with a few steps to take:
MongoProperties.getMongoClientDatabase(…) has to use ConnectionString instead of MongoClientURI as MongoClientURI comes only with the blocking driver.MongoMappingContext and MongoCustomConversions beans outside of MongoDataAutoConfiguration.@DBRef resolution as we cannot resolve document references with the reactive driver anymore. Reference resolution works only because the blocking driver is on the classpath. This means, that MappingMongoConverter must be created with a different DbRefResolver, depending on which drivers we have on the classpath. If the blocking one is available (or both drivers), then MongoMappingContext is configured like now. If only the reactive one is configured, then we need to provide a different DbRefResolver, which isn't available yet.spring-boot-starter-data-mongodb-reactive requires different dependencies: We need to remove org.mongodb:mongodb-driver and add org.mongodb:bson instead.org.bson.types.CodeWScope that comes only with the blocking driver so we need to have an alternative for that one, e.g. org.bson.types.CodeWithScope)We'll apply the Spring Data MongoDB changes within DATAMONGO-1919.
/cc @christophstrobl
I've been having the same issue, I found a different way on configuring my reactive mongo client, but it feels quite hacky and now my reactive mongo health indicator does not work, as there is a conflict with the reactive mongo template which is overriden.
I can only get my reactive mongo health indicator to work, when I remove the exclude autoconfigurations, but then however two mongo clients are registered, one blocking and resolving to localhost, so it seems a bit of a gamble to me ;)
Looking forward to see it fixed!
What will happen if an application contains both a blocking as reactive mongo client. Will we be able to get two health indicators? As they will operate on two different connections according to: https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.reactive.repositories.usage
Please also note that your application will operate on two different connections if using Reactive and Blocking Spring Data MongoDB Templates and Repositories.
Would it be possible to have a health indicator for both clients / connections?
Will we be able to get two health indicators?
Not ouf of the box, no. Why do you want that anyway? When those clients are created via auto-configuration, they point to the exact same MongoDB service so two clients are unnecessary IMO. If you have more questions, please join us on Gitter as we don't use the tracker for questions.
@wilkinsona , @mbhave we've just pushed the decoupling bits (DATAMONGO-1919) for SD-MongoDB 2.1 to master. To use the reactivestreams driver without the sync one, both org.mongodb.mongodb-driver-reactivestreams:1.9.0 and org.mongodb.bson:3.8.0 are required.
The change should allow you to proceed with the required ones on your side.
thanks @christophstrobl.
@wilkinsona we've targeted this issue for 2.0.x. The change requires org.mongodb.mongodb-driver-reactivestreams:1.9.0 and org.mongodb.bson:3.8.0 so looks like we need to move it to 2.1.x (unless it can be backported to org.mongodb.mongodb-driver-reactivestreams:1.7.x and org.mongodb.bson:3.6.x).
Agreed. Let's move this to the backlog.
Most helpful comment
Decoupling is possible with a few steps to take:
MongoProperties.getMongoClientDatabase(…)has to useConnectionStringinstead ofMongoClientURIasMongoClientURIcomes only with the blocking driver.MongoMappingContextandMongoCustomConversionsbeans outside ofMongoDataAutoConfiguration.@DBRefresolution as we cannot resolve document references with the reactive driver anymore. Reference resolution works only because the blocking driver is on the classpath. This means, thatMappingMongoConvertermust be created with a differentDbRefResolver, depending on which drivers we have on the classpath. If the blocking one is available (or both drivers), thenMongoMappingContextis configured like now. If only the reactive one is configured, then we need to provide a differentDbRefResolver, which isn't available yet.spring-boot-starter-data-mongodb-reactiverequires different dependencies: We need to removeorg.mongodb:mongodb-driverand addorg.mongodb:bsoninstead.org.bson.types.CodeWScopethat comes only with the blocking driver so we need to have an alternative for that one, e.g.org.bson.types.CodeWithScope)We'll apply the Spring Data MongoDB changes within DATAMONGO-1919.
/cc @christophstrobl