How to Use Hibernate OGM to Integrate Hibernate With MongoDB
- Hibernate OGM in MongoDB
- Importance of Using Hibernate OGM
- Use Hibernate OGM to Integrate Hibernate With MongoDB
In this article, we’ll learn the importance of Hibernate Object/Grid Mapper (OGM) and use it to integrate Hibernate with MongoDB.
Hibernate OGM in MongoDB
Hibernate Object/Grid Mapper (OGM) provides us with Java Persistence API (JPA) support for the NoSQL datastores. Remember that NoSQL is the parent term that covers all the child variety of data storage.
For instance, it includes documents, key-value, graph-oriented and column-oriented datastores.
Importance of Using Hibernate OGM
To understand its importance, you must know any relational database, Hibernate and MongoDB on a basic level. Assuming that you have basic knowledge of all (at least one relational database, Hibernate and MongoDB).
The Hibernate maps Java Objects, more precisely properties (also refers as fields), to the columns in a database table. Let’s take an example where a students
can have multiple courses
.
In a relational database, we can model this by containing a students
and courses
table where multiple entries in the courses
table can map to one student in the students
table.
create table students {
id integer(10),
name varchar(100),
department varchar(100)
}
create table courses {
id integer(10),
course1 varchar(50),
course2 varchar(50),
}
create table student_courses {
student_id integer(10),
course_id integer(10)
}
We can represent a similar relationship in Java, something as follows.
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="student_courses", joinColumns={@JoinColumn(name="student_id ", referencedColumnName="id")}
, inverseJoinColumns={@JoinColumn(name="course_id", referencedColumnName="id")})
private Set<CoursesEntity> courses;
While MongoDB is a NoSQL database, it stores and accesses the data through key-value pairs. Remember that the value section is stored as a document in JSON
/XML
format.
If we store the previous example of students
and courses
, it will look as follows in MongoDB.
{
id: 1,
name: "John",
department: "Comptuer Science"
courses: [
{
course1: "C Programming",
course2: "Machine Learning"
},
{
course1: "Recommender Systems",
course2: "Data Science"
}
]
}
As we can see that MongoDB has nested fields that can go even more in-depth, we can not use Hibernate with MongoDB by following traditional methods to map Java fields/properties to a document.
This is where we need Object/Grid Mapper (OGM). Hibernate provides us with an OGM engine implementation that extends its functionality and features to support NoSQL datastores, for instance, MongoDB.
The OGM also offers the benefit of querying data by using native queries of the language of our specific NoSQL database along with Java Persistence Query Language (JPQL), also refers as Java Persistence API (JPA).
The primary advantage of using OGM is the Java Persistence API’s consistency across NoSQL and relational datastores. The Hibernate OGM can provide an abstraction over various NoSQL datastores due to two key interfaces, GridDialect
and DatastoreProvider
.
This is why every new NoSQL datastore supported by Hibernate OGM comes with the implementation of DatastoreProvider
and GridDialect
interfaces.
As of today, although Hibernate OGM does not supports all the NoSQL datastores but is capable of working with many of them, including Infinispan
(key-value), Neo4j
(graph), and MongoDB
(document).
Use Hibernate OGM to Integrate Hibernate With MongoDB
We need to set up the following to use Hibernate OGM for integrating Hibernate with MongoDB.
- Java (we are using Java 18.0.1.1).
- MongoDB Server (we are using MongoDB 5.0.8).
- Code Editor or Java IDE (we use Apache NetBeans IDE 13).
- Dependencies using Maven or Gradle (we are using Maven).
Here, we will create a class named Student
that would be treated as an Entity
, and the properties of the Student
class will be taken as field
names in MongoDB. We use annotations to map Java classes to entities and properties to fields.
Let’s prepare the required files for that first. Write pom.xml
File (this file contains all the required dependencies):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.voidtesting.hibernatewithmongodbusingogm</groupId>
<artifactId>HibernateWithMongoDBUsingOGM</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<exec.mainClass>
<!--this name will be on single line, we are splitting it
for readability purpose-->
com.voidtesting.hibernatewithmongodbusingogm
.HibernateWithMongoDBUsingOGM
</exec.mainClass>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-mongodb</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>narayana-jta</artifactId>
<version>5.9.2.Final</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.parboiled</groupId>
<artifactId>parboiled-java</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossts</groupId>
<artifactId>jbossjta</artifactId>
<version>4.16.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.9.Final</version>
</dependency>
</dependencies>
</project>
Write persistence.xml
File (Here, we configure the given JPA persistent unit):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="https://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">
<persistence-unit name="ogmdemo" transaction-type="JTA">
<!-- Use the Hibernate OGM provider: configuration will be transparent -->
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>com.voidtesting.hibernatewithmongodbusingogm.Student</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"
/>
<!--
Here you will pick which NoSQL technology to use, and configure it;
in this example we use MongoDB.
-->
<property name="hibernate.ogm.datastore.provider" value="MONGODB"/>
<!-- Define MongoDB access parameters here. -->
<property name="hibernate.ogm.datastore.host" value="127.0.0.1"/>
<property name="hibernate.ogm.datastore.port" value="27017"/>
<property name="hibernate.ogm.datastore.create_database" value="true"/>
<property name="hibernate.ogm.datastore.database"
value="HibernateMongoDBDemo"/>
</properties>
</persistence-unit>
</persistence>
Ensure you have the persistence.xml
file in the src/main/resources/META-INF
directory. Otherwise, you may get errors.
Create Student.java
Class (this class will be mapped as an entity and its variables as fields in MongoDB):
package com.voidtesting.hibernatewithmongodbusingogm;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Student implements Serializable {
@Id public int id;
public String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public Student() {}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
You may notice that we used annotations @Entity
and @Id
to tell the MongoDB that creates an entity for this class and name it as Student
where the primary key would be id
. You can find all JPA annotations here.
Create Java Main Class:
package com.voidtesting.hibernatewithmongodbusingogm;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class HibernateWithMongoDBUsingOGM {
public static void main(String args[]) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ogmdemo");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// perform operations here
Student std = new Student(1, "Mehvish Ashiq");
entityManager.persist(std);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
Here’s a screenshot to know all files’ correct location in Java Project.
Now, execute the program. You can observe the following output to see how we execute and ensure everything is working fine.
Output: