Connection to non existing mongodb server does not throw exception - java

I'm playing around a bit with the MongoDB driver for Java. So I just created a simple application to connect to a MongoDB server and select a database.
So I created an instance of MongoClient and selected a 'DB':
try
{
MongoClient client = new MongoClient("localhost", 27017);
DB database = client.getDB("example");
}catch(Exception e){
e.printStackTrace();
}
Because of the fact that there is no running instance of mongod on my machine, I expected that client would throw an Exception. Unfortunately that isn't the case.
Even when selecting the database nothing happens. It just behaves like if there was a running mongod instance.
I looked into the documentation about the Java driver but couldn't find anything about it. Same with Google.
Is there anything I missed?
I'm using the latest MongoDB driver (version 2.12.2) from the official website.

It is expected behaviour. The driver does not attempt to connect to the database until it is needed. If you try the mongo shell, you do not get the error if the database does not exist.
When you try to insert a document into a non-existent collection it is created for you automatically and that is when the connection is lazily established. It is first when you actually perform some db operation (find(), insert() etc.) that the connection is checked for.

Try doing an insert to a collection. Connections are lazily initialized and validated.

Related

Does JDBC template cache connection?

I have an java-spring web application, which will read, write and delete information from a user upload SQLite DB. I am using JDBCtemplate to set connection, query the DB and update the information.
I observed one behavior during my tests:
Every time,after users uploaded a new SQLite db file(it will has the same name, place at the same directory as the old DB file), if they do not reboot/restart tomcat, jdbcquery will report the db was corrupted exception.
To me this looked like the JDBCtemplate somehow cached the connection and is trying to resume the connection with the old db?
If so, do you know anyway to refresh the connection without rebooting the application?
final SingleConnectionDataSource dataSource = new singleConnectionDataSource();
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new applicationException(MessageTemplateNames.GENERAL_UNKNOWN_ERROR, e);
}
createDirectoryForDbIfNotExists();
dataSource.setUrl(String.format("%s%s", JDBC.PREFIX, getDbFileLocation()));
dataSource.setAutoCommit(true);
JDBCTemplate does not handle connection.It obtains the connection from the datasource set to it.
From the reference documentation for SingleConnectionDataSource
Implementation of SmartDataSource that wraps a single JDBC Connection
which is not closed after use. .....
This is primarily intended for testing. For example, it enables easy
testing outside an application server, for code that expects to work
on a DataSource. In contrast to DriverManagerDataSource, it reuses the
same Connection all the time, avoiding excessive creation of physical
Connections.
A DriverManagerDataSource will suite your requirement to get a new connection without reboot
Simple implementation of the standard JDBC DataSource interface,
configuring the plain old JDBC DriverManager via bean properties, and
returning a new Connection from every getConnection call.
Update
My answer might not solve your original problem , but will only answer the question for new connection without reboot. Please go through #Thilo's comment on the same.

Lotus Notes Java replication of remote database

I have a lot of Lotus Notes / Domino (version 7) database to migrate to a new software.
On my workstation (with Lotus Notes installed), I'm using a standalone Java application to connect to a local replica an extract data.
However the replication of the distant database is still a manual process. I'd like to automatise it.
My java code basically looks like this :
Session localSession = NotesFactory.createSession(); // With Notes thread initialized
Session remoteSession = NotesFactory.createSession(SERVER, USER, PASSWORD);
Database localDb = localSession.getDbDirectory(null).openDatabase("local_name", true);
Database remoteDb = remoteSession.getDbDirectory(null).openDatabaseByReplicaID(REPLICA);
// ***EDITED CALLING INSTANCE BELOW***
remoteDb.createReplica(null, "local_name"); // Error thrown here
However the last line throws an exception (from memroy, but something like)
CN=****/***** does not have the right to create database on a server
How is it possible that I don't have the right to create database on my local computer ?
Is there any other way to programmaticly create a local replica from a distant database ?
Edit: changed calling instance of create replica to match my code causing the issue
My guess is that it's just giving you the wrong error message. One thing that's definitely wrong is that he first argument for createReplica should be an empty string, not a null pointer. I.e., try this:
localDb.createReplica("", "local_name");
Ok it looks like I found the answer.
AFAIU I had to open the database on the target server, using my local session, and run the createReplica() from here. This way, the createReplica is executed on my local Lotus Notes server, and the replica is created locally.
Session localSession = NotesFactory.createSession((String)null, (String)null, PASSWORD);
DbDirectory remoteDbDirectory = localSession.getDbDirectory(remoteSession.getServerName());
Database localSessionRemoteDatabase = remoteDbDirectory.openDatabaseByReplicaID(REMOTE_REPLICA_ID);
localSessionRemoteDatabase.createReplica("", LOCAL_FILE_NAME);
#Richard Schwartz Can you confirm this is ok ?
The only weird thing, is that it opens a prompt (like when it's expecting password) but the replica is created.
The process is executed within Eclipse.

com.allanbank.mongodb Java Mongodb Async driver error - Could not bootstrap a connection to the MongoDB servers

I'm implementing web services using google guice framework, here I injected mongodb module with constructor initializes mongodb connection. Here for every method I am using MongoClient and do stuff then I close connection after getting results. The problem is that if there is extensive heavy computations connection get closed and give error could not bootstrap connection error. please find the way to implement mongodb connection that will keep alive or restart communicating...
try{
MongoDBModule module = new MongoDBModule();
MongoClient mongoClient = module.getMongoDBClient();
MongoDatabase database = mongoClient.getDatabase(m_client.getDatabaseName());
MongoCollection collection = database.getCollection("CAMPUS_PROD");
//do stuff with mongoclient
mongoClient.close();
return document.resuls
}catch(IOException ie){
// print exception
}
Like all MongoDB drivers you should not create and close the MongoClient per-request. Instead you want to find a way to create a MongoClient when the application starts and then close it when the application exits.
In your case I would have your Guice Binder create the MongoClient and then do a bind(...).toInstance(...). e.g.,
bind(MongoClient.class).toInstance(mongoClient);
In the classes that use the MongoClient you should not call close().
The "cannot bootstrap" error is caused when the first request triggers the MongoClient to discover the MongoDB cluster and we could not create a connection to any of the servers. This could easily be caused by the connection thrashing causing by opening and closing the MongoClient.

MongoDB, Java: accessing cursor opens connection that cannot be closed

I have problem to close a connection that is always created after accessing the MongoDB cursor.
I am gathering the information about the connections from the console of the running mongod instance. I am not using any mongodb replication nor sharding yet.
For example a sample code causing an opened connection (assume 'myQuery' is just some query, coll is mapped using setInternalClass to the class MyObject):
DBCursor find = coll.find(myQuery);
List<MyObject> myObjects = new ArrayList<MyObject>();
while(find.hasNext()) { // this line opens the connection
MyObject next = (MyObject) find.next();
myObjects.add(next);
}
find.close(); // this line will not close the connection
You are calling close on your find object, which is a DBCursor. As mentioned in the API Documentation this will close only the cursor, not the underlying connection. To close the connections you should call close on the Mongo/MongoClient object, which either inherits or has a close function that will as per the API close all connections to the MongoDB server instance.

How to switch Databases using Java-JDBC

I have 2 databases, Derby DB and Oracle DB. My logic is to check if the Derby DB is active. If yes, I will send SQL queries to it. If the Derby DB is not active I want to create a connection pool to Oracle and perform the SQL updates there.
Is there any way to do this?
You can do it in the following way.
1)Load the Driver for Derby DB and try to connect to the database, if it throws the Exception then u can handle it in catch block.
2) Load the Driver for Oracle DB and connect to the database and do your transactions.
In this way you can do it...
You can used as many database connection as you want. You just need to create the connection provider that will serve the logic. In that connection provider you first create a connection to Derby if fail then try to Oracle.
What you need to assure is that you have proper drivers to both database and proper connection string.
TO assure that you have class
Class.forName("oracle.jdbc.driver.OracleDriver");
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
In case then a class is not found above code will throw Exception
About Derby Connection String
About Oracle Connection String
I also advise you to read JDBC Tutorial, and when your project will evolve you might want to use some ORM.
Good luck!
you could try something like this i suppose:
getDerbyConnection();
if(derbyConnectionActive) {
//execute queries on derbyDb
}
else {
getOracleDBConnection();
//execute queries on Oracle
}

Categories