How best to connect to MongoDB from a JEE6 application

655 views
Skip to first unread message

Hank

unread,
Mar 25, 2010, 9:58:18 AM3/25/10
to mongodb-user
I'm currently developing a JEE6 application which uses MongoDB as a
fast "cache" with superb query capabilities. Deployment is on
Glassfish v3.0.1 and I'm using the mongo Java drivers 1.3.

Currently I'm connecting to the DB from a stateless session bean. At
bean initialisation, I am connecting to the DB:

@PostConstruct
private void initialize() {
try {
m = new Mongo( properties.getProperty("serverName"), new
Integer(properties.getProperty("portNumber")) );
db = m.getDB(properties.getProperty("databaseName"));
coll = db.getCollection(properties.getProperty("collectionName"));
} catch (Exception e) {
e.printStackTrace();
}
}

From a performance point of view, is that a good way? From reading the
Java API, the Mongo() object returns a database instance from a pool.
Stateless session beans are also pooled within the JEE container.

I guess alternatively it could be injected as a (custom-)resouce, but
I guess I would need a factory then... Has anyone done this stuff
before?

Cheers,
Hank

Eliot Horowitz

unread,
Mar 25, 2010, 10:53:54 AM3/25/10
to mongod...@googlegroups.com
Mongo contains a connection pool.
So generally you want 1 Mongo instance per jvm.

> --
> You received this message because you are subscribed to the Google Groups "mongodb-user" group.
> To post to this group, send email to mongod...@googlegroups.com.
> To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.
>
>

Hank

unread,
Mar 25, 2010, 11:25:52 AM3/25/10
to mongodb-user
Thanks. That would be a Singleton EJB (as far as I understand JEE6).
I will try that and report back.

Cheers,
Hank

Robert McIntosh

unread,
Mar 25, 2010, 11:29:10 AM3/25/10
to mongod...@googlegroups.com
or set it up in JNDI if possible?

Hank

unread,
Mar 25, 2010, 11:38:25 AM3/25/10
to mongodb-user
On Mar 25, 4:29 pm, Robert McIntosh <pocke...@gmail.com> wrote:
> or set it up in JNDI if possible?

Yes, that would be ideal of course. But AFAIK you would do this as a
<custom-resource />, and that requires a FactoryClass. I have played
around a bit with custom resources, but was not very successful
unfortunately.

> > On Mar 25, 3:53 pm, Eliot Horowitz <eliothorow...@gmail.com> wrote:
> >> Mongo contains a connection pool.
> >> So generally you want 1 Mongo instance per jvm.

A follow-up question to Eliot: if m = new Mongo(host, port) is needed
only once per JVM, what about db = m.getDB( "mydb" );
Should that be requested per thread accessing Mongo? Is that an
"expensive" operation?
Or should that also be instantiated once and handed around (lets
assume concurrency is not an issue)?

I assume getting a collection is reasonably cheap, right? Should be
done at every access, just before executing a query...

Eliot Horowitz

unread,
Mar 25, 2010, 11:40:55 AM3/25/10
to mongod...@googlegroups.com
DB and DBCollection objects are cached, so doesn't really matter.

kaleigh

unread,
Apr 10, 2012, 7:09:43 PM4/10/12
to mongod...@googlegroups.com
Hank <hankipanky@...> writes:

Hi - I'm also developing a JEE6 application which uses MongoDB. I'm having
trouble with the Mongo Java Driver when I deploy my app using GlassFish. I can
successfully connect to Mongo from tests (outside Glassfish container). I also
tried repackaging the Mongo driver with javax.management and using the
repackaged jar as a dependency in my pom.xml. Did you also face this problem?
Any help is greatly appreciated!

java.lang.ClassNotFoundException: javax.management.JMException not found by
com.mongodb [257]
at org.apache.felix.framework.BundleWiringImpl.
findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
at org.apache.felix.framework.BundleWiringImpl.
access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$
BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at com.mongodb.DBTCPConnector.<init>(DBTCPConnector.java:35)
at com.mongodb.Mongo.<init>(Mongo.java:138)
at com.mongodb.Mongo.<init>(Mongo.java:124)
at com.mongodb.Mongo.<init>(Mongo.java:114)
at com.renttherunway.userservice.
ServiceLayer.initMongoDB(ServiceLayer.java:36)

Thanks,
Kaleigh.

schaffer

unread,
Apr 11, 2012, 7:40:34 AM4/11/12
to mongod...@googlegroups.com
The easiest solution I have found is to ignore the EJB specific functionality and use POJOs which are accessed by the factory pattern and clear interfaces.
Place all of your mongoDB access code into a "data access layer" jar which gets called from your other code.
This enables you to test the code from outside the application server and also allows better reuse.

As stated above Mongo handles its own connection pooling.
However, just to be aware, if you are deploying as EARs, each EAR has its own JVM so will have a new instance of MongoDB per deployment.

schaffer

unread,
Apr 11, 2012, 7:42:45 AM4/11/12
to mongod...@googlegroups.com
How are you deploying your code?
Reply all
Reply to author
Forward
0 new messages