
In the real world of enterprise application, Relational Database Management System (RDBMS) is dominant product. There are several most widely used propeitry and opensource products, the most well known and popular propeitary products are Oracle Database, IBM DB2, Microsoft SQL Server and for the opensource products are MariaDB, PostgreSQL. The reasons for RDBMS is so popular in the market over any kind of database are, they provide enterprise feature such as high availabiltiy, security, consistency and support whether from the corporate or communities. The most important feature that push RDBMS to be top of the choice for database that deployed on any production application is ACID complied feature. ACID property ensure consistency, integrity and durability of the database system, this property is mandatory for transaction management which is required especially in the banking and financial market's data processiong.
ACID property asure data consistency, integrity and durability, but it also comes with obstacles. it is very hard to scale out the system that comply with ACID property once the data volume is grow. In some industry, ACID property is not mandatory such as IoT, BigData, AI, this is where NOSQL database comes in the picture. Recently, NOSQL database like MongoDB, CouchDB, Cassanda is becoming very popular among companies in the industry.
Once you use NOSQL database, you need to adjust your concept about how data is arrange by those database management system. It is quite a challenge to adapt and learn how thing works and also this is time consuming. To minimize those gap between the differences between RDBMS and NoSQL, Hibernate provides object mapping for NoSQL database beside RDBMS to reduce the gap between those system. Below is how Hiberate OGM interact with MongoDB.
The greate benefit for leveraging Hibernate OGM is being able to use JPA to perform data query. This way, you don't need to worry about figure out how to perform new scheme of query. In this post, we will demonstrate how to leverage Hibernate to handle object and database mapping, for the database we use MongoDB as our DBMS and we will retreive data by JPQL. Below is the content of this article.
Table Content
- MongoDB Environment Setup
- Create JPA Project
- Create EJB Project
- Create Web Project
- Test Project On Wildfly
- Reference
1.MongoDB Environment Setup
Before we start create application project, we need to set up our MongoDB database. First, we need to set up username and password for authentication. Mostly in the production Environment, it will require SSL/TLS for data encryption. But in this post, we will need just username and password. To create user and password in MongoDB, we use below script.
$mongo --port 3309 --authenticationDatabase admin -u admin -p
>use db01
>db.createUser(
{
user: "user01",pwd:"password", roles: [ { role: "readWrite", db: "db01" }, "readWrite" ]
}
)
Now, we are ready to create our java ee application to connection to MongoDB.
2.Create JPA Project
For Java EE Application, first we need to create JPA project to map Java Object with data collection in the database. After creating JPA project, my project, entity classes, persistence.xml and pom.xml become as below.
For dependency, we convert JPA project into Maven project and add dependencies as below
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://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>pro.itstikk</groupId>
<artifactId>java-ee-09-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>java-ee-09-jpa</name>
<url>https://blog.tikkwiki.pro</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-bom</artifactId>
<version>4.1.2.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-core</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</dependency>
</dependencies>
<build>
<finalName>java-ee-09-jpa</finalName>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
For Entity class, we create Book.java class
package pro.itstikk.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="booktbl")
public class Book {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
@Column(unique=true)
private String sid;
private String name;
private String author;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
And persistence.xml is create as following
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="java-ee-09-jpa">
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>pro.itstikk.entity.Book</class>
<properties>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>
<property name="hibernate.ogm.datastore.database" value="db01"/>
<property name="hibernate.ogm.datastore.host" value="localhost"/>
<property name="hibernate.ogm.datastore.port" value="3309"/>
<property name="hibernate.ogm.datastore.provider" value="mongodb"/>
<property name="hibernate.ogm.datastore.username" value="user02" />
<property name="hibernate.ogm.datastore.password" value="password" />
</properties>
</persistence-unit>
</persistence>
If we look closely, every thing in the class is look just like normal JPA class for RDBMS.
3.Create EJB Project
To manipulate the data in MongoDB, we create EJB project. we have create EJB project as below.
In the EJB project, we need to import JPA project that we just created. And for BookDao.java, we create EJB as following
package pro.itstikk.dao;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import pro.itstikk.entity.Book;
@Stateless
public class BookDao {
@PersistenceContext
private EntityManager em;
public void save(Book book) {
em.persist(book);
}
public List<Book> getAllBooks(){
TypedQuery<Book> query = em.createQuery("FROM Book b",Book.class);
List<Book> list = query.getResultList();
return list;
}
}
then, we finished for EJB class
4.Create Web Project
Next, we will create dynamic web project to provide interface for our application. In this project, we just create JSF application by converting our web application and create pom.xml to import all dependencies into the project. In this project, we will create two interface to provide data persistence and fetch data from database.
In Dynamic web application project, we need to import JPA and EJB that we created above. For pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://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>pro.itstikk</groupId>
<artifactId>java-ee-09-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>java-ee-09-web</name>
<url>https://blog.itstikk.pro</url>
<dependencies>
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>richfaces</artifactId>
<version>4.5.1.Final</version>
</dependency>
</dependencies>
<build>
<finalName>java-ee-09-web</finalName>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>webapps</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
And for web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>java-ee-09-web</display-name>
<welcome-file-list>
<welcome-file>default.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.skin</param-name>
<param-value>blueSky</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
Create managed bean (BookBean.java) to bind with views
package pro.itstikk.bean;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import pro.itstikk.dao.BookDao;
import pro.itstikk.entity.Book;
@Named("bookBean")
@RequestScoped
public class BookBean {
private Book book;
private List<Book> books;
@EJB
private BookDao bookDao;
@PostConstruct
public void init() {
book= new Book();
}
/**
* action method
* @return
*/
public String save() {
bookDao.save(book);
return "result.xhtml";
}
public String find() {
books = bookDao.getAllBooks();
return "resultList.xhtml";
}
/**
* setter and getter for objects
* @return
*/
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}
Then, we create xhtml files. First, we create default.xhtml for data persistence as following
Next is result.xhtml to show result after we persisted the data.
To fetch the data and show in the page, we create below
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html">
<h:head></h:head>
<body>
<rich:panel>
<f:facet name="header">
Write your own custom rich components with built-in AJAX support
</f:facet>
<div id="body">
<h:form>
<h:commandButton action="#{bookBean.find()}" value="search" />
</h:form>
</div>
</rich:panel>
</body>
</html>
to show fetcing result, we create below xhtml file.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html">
<h:head></h:head>
<body>
<rich:panel>
<f:facet name="header">
Write your own custom rich components with built-in AJAX support
</f:facet>
<rich:dataTable var="aBook" value="#{bookBean.books}">
<f:facet name="header">
<rich:columnGroup>
<rich:column>
<h:outputText value="Sid" />
</rich:column>
<rich:column>
<h:outputText value="Name" />
</rich:column>
<rich:column>
<h:outputText value="Author" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="#{aBook.sid}" />
</rich:column>
<rich:column>
<h:outputText value="#{aBook.name}" />
</rich:column>
<rich:column>
<h:outputText value="#{aBook.author}" />
</rich:column>
</rich:dataTable>
</rich:panel>
</body>
</html>
5.Create Java EE Project
After creating JPA, EJB and Web project, we need to pack all the projects into EAR file and deploy Wildfly Application server. But to deploy hibernate ogm in ear project. You need to create jboss-deployment-structure.xml as below.
For jboss-deployment-structure.xml, we create as below
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<dependencies>
<module name="org.hibernate.ogm" slot="main" services="import" />
<module name="org.hibernate.ogm.mongodb" services="import" />
<module name="org.hibernate.search.orm" services="import" />
</dependencies>
</deployment>
</jboss-deployment-structure>a
In wildfly applicatio, we need to import two packages into Wildfly by downloading below packages;
This should work if you have the ogm modules under WILDFLY_HOME/modules/org/hibernate/ogm/main. Now we are ready to deploy ear project into wildfly. Once deployed the packages, you should get below results.
hey man....i could not connect with this project to mongodb atlas...would u make a project for that one too
ReplyDelete