How to Use Hibernate OGM to Integrate Hibernate With MongoDB

Mehvish Ashiq Feb 02, 2024
  1. Hibernate OGM in MongoDB
  2. Importance of Using Hibernate OGM
  3. Use Hibernate OGM to Integrate Hibernate With MongoDB
How to 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.

  1. Java (we are using Java 18.0.1.1).
  2. MongoDB Server (we are using MongoDB 5.0.8).
  3. Code Editor or Java IDE (we use Apache NetBeans IDE 13).
  4. 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.

use hibernate ogm to integrate hibernate with mongodb - all files

Now, execute the program. You can observe the following output to see how we execute and ensure everything is working fine.

Output:

use hibernate ogm to integrate hibernate with mongodb - final output

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook