MongoDB on WildFly using Hibernate OGM – pt 1
Recently, I was developing some services based on Openshift, the Red Hat’s Service As a Platform, and I choose to use WildFly 8.2 as application server, and MongoDB 2.4 to store my data. Since it was my first time using MongoDB, I had to study how to communicate from my EJBs to the database, and I’ve found that I could use either Morphia or Hibernate OGM. The second one gives you drivers to communicate with other NOSQL databases, so I choose Hibernate OGM, and started to configure my project and the application server to use it. As I thought, it was not so easy like every guide or official documentation tells, so here I will explain how I successfully made it work.
I will not explain here how to set up WildFly nor MongoDB. For those, the official documentations are the best places where to find informations, so here are the links:
As I said, I choose Hibernate OGM, and in the moment I write this article, the latest final version is the 4.1.3, so I will refer to this version in the rest of the article. You can also refer to the official Reference Guide.
Modules: let’s add to WildFly the NOSQL declination
WildFly is the newest JBoss’s application server (AS from now on). It already includes full support for Hibernate, but not for the NOSQL declination, so we need to configure it directly on the AS, and we can do it adding the right modules. Modules for Hibernate OGM can be downloaded here. The archive contains all the JARs and XMLs that have to be added to WildFly in order to make OGM works with a NOSQL database. In particular, the archive contains the JAR files for supporting MongoDB, but also CouchDB, InfiniSpan and Neo4J. To make MongoDB work, only its JARs need to be added, but I added all the modules as they are in the archive. When I deployed my war file to my OpenShift application, I had to add the same modules on the remote installation of WildFly, simply sending all the modules with SFTP and restarting the AS.
Dependencies, because WildFly has to know it
Simply adding modules in WildFly is not enough to use those modules in an application. That is because of the way WildFly works with modules. In fact, as the official documentation explains, I had to add an xml file into my project, to tell WildFly that my application will require one of those modules I previously added. I created, then, a Dynamic Web Application Project in Eclipse, and added a jboss-deployment-structure.xml file into WebContent > WEB-INF, as shown in the below image.

The content of the file is the following one:
1 2 3 4 5 6 7 8 |
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.hibernate" slot="ogm" services="export" /> <module name="org.hibernate.ogm.mongodb" slot="main" services="export" /> </dependencies> </deployment> </jboss-deployment-structure> |
With this code, I simply tell WildFly that it needs to load two modules: org.hibernate and org.hibernate.ogm.mongodb. Obviously, since I have already set the modules in WildFly, it already know all the required dependencies of these two modules, and will load all of them dependencies.
Project’s dependencies
Once I have set up everything on the AS side, it is time to start to code. In my project, I added the dependency below in the maven POM file:
1 2 3 4 5 6 7 |
<dependencies> <dependency> <groupId>org.hibernate.ogm</groupId> <artifactId>hibernate-ogm-mongodb</artifactId> <version>4.1.3.Final</version> </dependency> </dependencies> |
Every settings are documented in the Official Hibernate OGM’s reference guide linked above.
Persistence unit
Once everything is settled with modules and dependencies, the next step is to configure a persistence unit that will be used to communicate with MongoDB. The persistence.xml file needs to be at the right location, that is WebContent > WEB-INF > classes > META-INF > persistence.xml, as shown in the picture below. Every other location will not work with Hibernate OGM and WildFly.

The content of the file is the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="ExamplePU" transaction-type="JTA"> <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider> <properties> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> <property name="jboss.as.jpa.providerModule" value="org.hibernate:ogm"/> <property name="hibernate.ogm.datastore.provider" value="mongodb"/> <property name="hibernate.ogm.datastore.database" value="exampleDB"/> <property name="hibernate.ogm.datastore.host" value="localhost"/> <property name="hibernate.ogm.datastore.port" value="27017"/> <property name="hibernate.ogm.datastore.username" value="admin"/> <property name="hibernate.ogm.datastore.password" value="admin"/> </properties> </persistence-unit> </persistence> |
All the values are self-explanatory. The “hibernate.ogm.datastore.provider” key is set to “mongodb”, as I am using MongoDB. It can be set with other values, as specified in the Hibernate OGM Official reference, if other Databases are used. I have choosen to refer to an exampleDB Database for this article, and the persistence unit is called “ExamplePU”. In this file, I will need to add a reference for each entity I will need to be handled by Hibernate OGM, as I will explain below in the article.
Entities
It’s time to create some entities. In this article, I used two entities: one to map a generic User, and one other, to map a generic Session, referenced by the User. Since I am using MongoDB, I want to embed the session directly into the user. Probably, there are better ways to design a relationship between users and sessions, but, in this article, I just want to show how to use entities and embeddable entities.
I created the class User, and decorated it with the annotation @Entity from the standard JPA. Below is the code, excluding for the setters and getters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.gregoriopalama.example.dao; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.bson.types.ObjectId; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private ObjectId id; private String username; private Session session; /* getters and setters */ } |
The @Id and @GeneratedValue annotations are also from JPA, since Hibernate OGM works with the standard JPA’s annotations. The id attribute must be of ObjectId type, in order to work with MongoDB and Hibernate OGM as an identifier. In the User class, there is a session attribute of the type Session. The Session class is listed below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.gregoriopalama.example.dao; import javax.persistence.Embeddable; import java.util.Date; @Embeddable public class Session { private Date startDate; private Date endDate; /* getters and setters */ } |
As I said before, I want to embed the session directly into the user, without creating a new document for the sessions. The @Embeddable annotation, then, tells MongoDB to embed the session directly into the user’s document. This will create, in MongoDB, something like the example below, where we can see the embedded session:
1 2 3 4 5 6 7 8 9 |
{ "_id" : ObjectId("adbcef0123456789"), "username" : "gregorio", "session" : { "startDate" : ISODate("2015-04-19T13:39:26Z"), "endDate" : ISODate("2015-04-29T13:39:26Z") } } |
Since I created a class decorated with the @Entity annotation, I had to tell Hibernate OGM to handle it, using the persistence.xml file. In that file, I simply added the reference to the User class. The reference to the Session class is not needed, because it is not annotated with @Entity. The persistence.xml file will then be as following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="ExamplePU" transaction-type="JTA"> <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider> <properties> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> <property name="jboss.as.jpa.providerModule" value="org.hibernate:ogm"/> <property name="hibernate.ogm.datastore.provider" value="mongodb"/> <property name="hibernate.ogm.datastore.database" value="exampleDB"/> <property name="hibernate.ogm.datastore.host" value="localhost"/> <property name="hibernate.ogm.datastore.port" value="27017"/> <property name="hibernate.ogm.datastore.username" value="admin"/> <property name="hibernate.ogm.datastore.password" value="admin"/> </properties> <class>com.gregoriopalama.example.dao.User</class> </persistence-unit> </persistence> |
The entity manager
I now needed to create some EJB layer that will help me to access to the data layer. Since I need an entity manager to communicate with MongoDB, I created a stateless EJB that provides all the entity managers I could set for my application. In this example, only one persistence unit is set, so my factory will only provide one entity manager. The code below does what I just described:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.gregoriopalama.example.provider; import javax.ejb.Stateless; import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Produces; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @Stateless public class EntityManagerFactory { @PersistenceContext(unitName = "ExamplePU") private EntityManager entityManager; @Produces @RequestScoped public EntityManager getEntityManager() { return entityManager; } } |
In the @PersistenceContext annotation, I specified the name of the persistence unit I have already set in the persistence.xml file.
Accessing the data
At this time, everything is ready to access datas, from writing it into the database, to reading it from the database. Since I used EJBs in my project, I firstly created an interface, in this way:
1 2 3 4 5 6 7 8 |
package com.gregoriopalama.example.repository; import com.gregoriopalama.example.dao.User; public interface UserRepositoryBeanLocal { public User insert(User user); public User findByUsername(String username); } |
The interface declares two methods, that are all I needed to start writing to and reading from my database, and below is the implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.gregoriopalama.example.repository; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.inject.Inject; import javax.persistence.EntityManager; import org.bson.types.ObjectId; import org.hibernate.ogm.OgmSession; import com.gregoriopalama.example.dao.User; @Stateless @LocalBean public class UserRepositoryBean implements UserRepositoryBeanLocal { @Inject EntityManager entityManager; @Override public User insert(User user) { entityManager.persist(user); return user; } @Override public User findByUsername(String username) { OgmSession ogmSession = entityManager.unwrap(OgmSession.class); User user = (User) ogmSession .createQuery("FROM User WHERE username = :username") .setParameter("username", username).uniqueResult(); return user; } } |
First of all, I created a stateless bean, so I can use it everywhere in my project just decorating an attribute with the @EJB annotation. I then added the reference to the entity manager, and injected the value provided from the factory I created above using the @Inject annotation.
The insert into the database is really simple and does not need any further explanation. Searching into the database using Hibernate OGM, instead, requires some attentions. I needed to obtain the session from the entity manager, and using that session, I can query my database, using HQL, the Hibernate Query Language. In the moment I write this article, Hibernate OGM does not support Criterias, so the only permitted options are using either QBE or HQL, and I definitely prefere the second one.
With this, I conclude this article. Obviously, everything explained here can be extended and used in better ways, but this is a good start if you just want to start using MongoDB in WildFly, connecting to it through Hibernate Search.
Every suggestion and correction is welcome!
EDIT: based on some updates in Hibernate and on comments, I added a 2nd part on this article. You can read it here.