How to set MongoDB ReadPreference in Spring MVC's contextConfigLocation
Solution 1
Expanding @Trisha's response in to an answer: "Do it in MongoTemplate programmatically" by setting the ReadPreference
to SECONDARY
.
MongoTemplate template = new MongoTemplate(...);
template.setReadPreference(com.mongodb.ReadPreference.SECONDARY);
Solution 2
Declare the following bean
<bean id="readPreferenceSecondary" class="com.mongodb.TaggableReadPreference.SecondaryReadPreference">
</bean>
and
you inject this in your mongotemplate
<bean id="mongoTemplateProdDb" class="org.springframework.data.mongodb.core.MongoTemplate" >
<property name="readPreference" ref="readPreferenceSecondary"></property>
</bean>
Solution 3
In case you are using spring-data-mongodb and have some requirement to use multiple Read Preferences based on find query, you can create multiple Mongo Templates and/or Repositories like
@EnableMongoRepositories(basePackages = {
"com.you.repo.package" }, mongoTemplateRef = "mongoTemplateOne")
@Configuration
public class MongoConfig {
@Bean(name="mongoTemplateOne")
public MongoTemplate getMongoTemplateOne() throws UnknownHostException {
MongoTemplate templateOne = new MongoTemplate(new SimpleMongoDbFactory(new MongoClientURI("YOUR_MONGO_URL")));
templateOne.setReadPreference(ReadPreference.secondaryPreferred());
//setting WriteConcern but not relevant for this thread
templateOne.setWriteConcernResolver(yourWriteConcernResolver());
return templateOne;
}
@Bean(name = "mongoTemplateTwo")
public MongoTemplate getMongoTemplateTwo() throws UnknownHostException {
MongoTemplate templateTwo = new MongoTemplate(new SimpleMongoDbFactory(new MongoClientURI("YOUR_MONGO_URL")));
templateTwo.setReadPreference(ReadPreference.secondaryPreferred());
return templateTwo;
}
private WriteConcernResolver yourWriteConcernResolver() {
return action -> {
if (action.getCollectionName()
.equals("your_collecton")
&& (action.getMongoActionOperation() == MongoActionOperation.SAVE
|| action.getMongoActionOperation() == MongoActionOperation.UPDATE)) {
return WriteConcern.MAJORITY;
}
return action.getDefaultWriteConcern();
};
}
Solution 4
In case you have more than one secondary (replica-set) you can be more specific and tell the mongo driver explicitly which of the secondaries you want to read from, using tags.
On the mongo side you run this command:
db.getMongo().setReadPref('secondaryPreferred',
[{"tagName":"TagVal1"},
{"tagName":"TagVal2"},
{}])
In the code it looks like this:
MongoTemplate template = new MongoTemplate(...)
template.setReadPreference(ReadPreference.secondaryPreferred("your DBObject that reflect your mongo tag names");
Hope it helps.
Comments
-
sorebrek almost 2 years
I am connecting to a MongoDB sharding server via mongodb java driver in Spring MVC. I am using the following versions:
- spring-webmvc-3.2.1.RELEASE
- mongo-java-driver/2.10.0/mongo-java-driver-2.10.0
- spring-data-mongodb-1.2.0.RELEASE
My Mongo options are set in the contextConfigLocation file mvc-dispatcher-servlet.xml
<mongo:mongo host="mongo.sample.com" port="30000"> <mongo:options auto-connect-retry="true" slave-ok="true"/> </mongo:mongo>
It works pretty well, but the slave-ok is deprecated by come.MongoDB.ReadPreference. I just wonder if there is any way to set the readPreference for Spring MVC in the contextConfiLocation file.