How to configure in memory embedded database for mongoDB similar to H2 Database in Spring Boot - mongodb

I am trying to configure in memory embedded Mongo database with Spring Boot similar to H2 Database. Is there any option available in Spring Mongo?

MongoDB does not have an in-memory storage engine.
You can use tmpfs or zram to create a partition backed by memory and store the data in that partition.

You can create In-memory mongodb-server by using following dependency
<dependency>
<groupId>de.bwaldvogel</groupId>
<artifactId>mongo-java-server</artifactId>
<version>1.38.0</version>
</dependency>
Then declare mongo client in config class
#Override
public MongoClient mongoClient() {
MongoServer server = new MongoServer(new MemoryBackend());
// bind on a random local port
InetSocketAddress serverAddress = server.bind();
return mongoClient=MongoClients.create(
MongoClientSettings.builder()
.applyToClusterSettings(builder ->
builder.hosts(Arrays.asList(new ServerAddress(serverAddress))))
.build());
}

Related

Javers async commit into Mongo DB

Looking for some proper documentation on async commit for mongo db . We have a spring boot app where we are trying to generate audits for our domain objects , we would like to commit the audits generated by javers into mongo db asynchronously while our main SQL based transaction is fr of this mongodb call. Any pointers on this would be really helpful.
If you are using the Javers Spring Boot Mongo starter, you can simply put the #JaversAuditableAsync ann on a repository method.
There are limitations:
It works only with Mongo and there is no integration for magical-autogenerated ReactiveMongoRepository yet. So you have to put the #JaversAuditableAsync on an actual method which does the save.
#Repository
interface DummyObjectReactiveRepository
extends ReactiveMongoRepository<DummyObject, String> { }
...
#Repository
class MyRepository {
#Autowired DummyObjectReactiveRepository dummyObjectReactiveRepository;
#JaversAuditableAsync
void save(DummyObject d){
dummyObjectReactiveRepository.save(d)
}
}

MongoDB URI Configuration

I am using MongoDB URI (mongodb://user:pass#IP:27017/myDB?retryWrites=false&connectTimeoutMS=10000) configuration in Spring-boot. I observed approx every 5 min. Mongodb not responding for first hit, Second hit working fine.
Some time getting this message "Opened connection [connectionId{localValue:8}]" in log.
Java Configuration.
#Bean
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(new MongoClientURI(prop.getDbConnectionUri()));
}
#Bean
public MongoTemplate mongoTemplate() {
log.info("Loging MongoDB Config Loging...");
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
return mongoTemplate;
}
Please suggest any other optional configuration required in Mongo URI.
After so many Changes,I fixed this problem by changing below system configuration. This is not related to mongo configuration.
Open sysctl.conf by using "sudo vim /etc/sysctl.conf" command.
Change "net.ipv4.tcp_keepalive_time = 220".
Save Changes.
Run "sysctl --system" command.
And Restart your micro service.
Now Mongo Connection working fine.

How to specify the using mongo database in a MongoRepository when there are multiple databases

In my spring boot application i have configured two databases in my yml file. So now I want to specify which database is to use in each MongoRepository. Is this possible? If so, how to do it? Thanks in advance.
yml file :
spring:
data:
mongodb:
first:
host: 127.0.0.1
port: 27017
database: db_admin
rest:
base-path: /admin
second:
host: 127.0.0.1
port: 27018
database: `user_forms`
rest:
base-path: /users
So in User MongoRepository i want to use the user_forms database.
The user MongoRepository :
#RepositoryRestResource(collectionResourceRel = "users",path = "users")
public interface UserRepository extends MongoRepository<User, String> {
List<User> findByUserId(String id);
}
Spring Boot auto configuration provides a default MongoTemplate to facilitate generating MongoDB Repositories.
Nevertheless if you want to use multi MongoDB databases, you would need to
register MongoTemplates for every MongoDB databases
designate each of the MongoTemplates to base packages of MongoRepositories accordingly, so that Spring Data MongoDB is informed to use the right template when generating repositories.
For example, say you registered 2 MongoTemplates, namely templateAdmin and templateUser, configured explicitly to their MongoDB. Then you could use code like this to inform Spring Data MongoDB which repositories use which template:
#EnableMongoRepositories(
basePackages = "com.the.base.package.name.of.admin.repositories",
mongoTemplateRef = "adminTemplateBeanName")
#Configuration
public class AdminMongoConfig {
#Bean
public MongoTemplate adminTemplateBeanName() {
//...
}
}
Configure Multiple MongoDB repositories with Spring Data Mongo Basically explained almost all points what I have said. So my wild guess is that you may have a misconception that MongoTemplate is irrelevant to MongoRepository, which is not the case.
Adding an answer despite having marked the question as a duplicate, as there is some confusion whether MongoRepository uses MongoTemplate.
When you inject your MongoRepository, it is proxied by an instance of SimpleMongoRepository class. it has a field
private final MongoOperations mongoOperations;
MongoOperations is an interface, and MongoTemplate is its implementation.
Now, the question is where does this default mongo template come from in a Spring Boot application.
Look at MongoDataAutoConfiguration
#Bean
#ConditionalOnMissingBean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory,
MongoConverter converter) {
return new MongoTemplate(mongoDbFactory, converter);
}
Therefore, I am still claiming it is a duplicate of: Configure Multiple MongoDB repositories with Spring Data Mongo

Intermittent TimeoutException connecting Atlas MongoDb from .net core 2.2 at Linux-based docker container on Azure

I have an application based using .Net Core 2.2 that is connecting to MondoDb cluster V3.6 in Atlas. The application is hosted in Azure as a Linux Docker container. The app is using MongoDB .Net driver 2.7.3. The app periodically (once in a couple minutes) receives the following timeout exceptions:
System.TimeoutException at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException
and
System.TimeoutException at MongoDB.Driver.Core.Connections.TcpStreamFactory.ConnectAsync
The mongo client instance is configured according to the MongoDb docs, i.e.
var url = MongoUrl.Create("mongodb+srv://user:password#cluster.gcp.mongodb.net/?authSource=admin&retryWrites=true&ssl=true");
var clientSettings = MongoClientSettings.FromUrl(url);
clientSettings.SslSettings = new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
void SocketConfigurator(Socket s) => s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
clientSettings.ClusterConfigurator = builder =>
builder.ConfigureTcp(tcp => tcp.With(socketConfigurator: (Action<Socket>)SocketConfigurator));
return new MongoClient(clientSettings);
I checked number of SO questions including MongoDB C# 2.0 TimeoutException and SocketTimeout with opened connection in MongoDB but the suggestions seem to be either outdated (reported as fixed in the current version of driver) or don't have permanent positive effect (setting timeouts in the connection string i.e. connectTimeoutMS=90000&socketTimeoutMS=90000&maxIdleTimeMS=90000). The second one (setting tcp_keepalive_time) seems to be not applicable to a docker container in Azure. Please help.
Have you tried setting like this:
var client = new MongoClient(new MongoClientSettings
{
Server = new MongoServerAddress("xxxx"),
ClusterConfigurator = builder =>
{
builder.ConfigureCluster(settings => settings.With(serverSelectionTimeout: TimeSpan.FromSeconds(10)));
}
});

Spring data configuration for mongodb

I am using spring data for storing and fetching records from the database. Initially the database was MySQL, but now I want to configure the same application for mongodb. Please the application resource properties for MysQL.
# ===============================
# = DATA SOURCE
# ===============================
# Connection url for the database connection
spring.datasource.url = jdbc:mysql://localhost:27017/purchase_books
# Username and password
spring.datasource.username = root
spring.datasource.password = root
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# ===============================
# = JPA / HIBERNATE
# ===============================
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update): with "update" the database
# schema will be automatically updated accordingly to java entities found in the project
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Allows Hibernate to generate SQL optimized for a particular DBMS
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
Can anyone please tell the configuration changes in case of mongodb ?
MySQL is an RDBMS and MongoDB is an Document Database.
Hibernate supports NOSQL Database in the form OGM (Object/Grid Mapper), Documentation on OGM http://docs.jboss.org/hibernate/ogm/4.2/reference/en-US/html/
Refer the below example for Spring, Hibernate and MongoDB
https://pragmaticintegrator.wordpress.com/2011/07/14/use-spring-and-hibernate-with-mongodb/
Moreover if you are using spring and if you want to remove Hibernate you can go for Spring MongoTemplate
Refer the sample in the below url
https://spring.io/guides/gs/accessing-data-mongodb/
spring.data.mongodb.uri=mongodb://localhost:27017/<database name>
spring.datasource.username= <username>
spring.datasource.password= <password>
#OR
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=<database name>
spring.data.mongodb.username=<username>
spring.data.mongodb.password=<password>