Object-relational Mapping Using JPA, Hibernate and Spring Data JPA

In this article series we will set JPA, Hibernate and Spring Data JPA face to face, compare and contrast them.

Object persistence means that information from the objects in an application can survive after that application ended its execution. Meaning that the information can be saved and retrieved. Persistence in Java will require object-relational mapping. Mapping the object instances to the tables of a relational database. There are a few alternatives to make this object-relational mapping, from which we analyze, compare, and contrast Jakarta Persistence API (JPA), Hibernate, and Spring Data JPA. Many applications require persistent data. If an information system does not save data when its execution stops, the practical use of the system will strongly diminish.

Managing persistent data may be a fundamental design decision in software projects. Can we use only SQL and stored procedures and triggers, or this problem must be addressed by Java frameworks? Should we write by ourselves even basic CRUD (create, read, update, delete) operations in SQL and JDBC, or should this work be handed to an intermediary layer? Relational Database Management Systems have proprietary SQL dialects, how can we address portability? [1] ORM (object/relational mapping) is now widespread. This is mainly due to Hibernate, an open-source ORM, and Spring Data, an umbrella project from the Spring family whose purpose is to unify and facilitate access to different kinds of persistence stores, including relational database systems and NoSQL databases.

Relational databases manage data integrity. This is mostly due to long-time established fundamentals of the relational data model [2][3].

Usually, data is needed and accessed much longer than the application managing them does [4]. This data independence principle will mean that the applications accessing data may change or disappear, while the logical structure of data should survive.

Object-relational Mapping Using JPA, Hibernate and Spring Data JPA.jpg

The JDBC API is the classical way to access databases from Java applications. One needs to create and open the connection to the database, write the query in a particular SQL dialect, bind the query parameters, execute the query, browse the results, then close the connection. So, data access is tedious and implies many boilerplate operations.

Hibernate is a project focused on managing persistent data in Java. The Hibernate suite includes projects as Hibernate ORM, Hibernate EntityManager, Hibernate Search, Hibernate Validator, Hibernate OGM, Hibernate Envers, or Hibernate Reactive [1].

Hibernate ORM belongs to the larger Hibernate framework suite. It provides a native proprietary API and a core for persisting information in databases. Hibernate ORM is at the ground of other projects belonging to the same suite. It is an independent framework and may be used on any modern Java version and eventually in combination with other frameworks (including here Spring and Jakarta Enterprise Edition) [1].

Spring Data is a family of projects belonging to the Spring framework whose purpose is to simplify access to both relational and NoSQL databases.

The Spring Data suite includes many projects, like Spring Data Commons, Spring Data JPA, Spring Data JDBC, Spring Data MongoDB, Spring Data Redis.

Spring Data JPA deals with the implementation of JPA-based repositories. It provides improved support for JPA-based data access layers by reducing the boilerplate code and creating implementations for the repository interfaces.
Hibernate and Spring Data are both frameworks. In a framework, the working flow is already included, there are hook points that we should fill out with the code to implement domain-specific functions.

A framework is more complex than a library. It defines a skeleton where the application may include its own features to fill out that skeleton. This way, the code will be called by the framework when appropriate. Developers need to focus mainly to implement the business logic.

Frameworks rely on the “Inversion of Control” idea. Libraries expose APIs that may be called from the developer’s applications. When the programmer writes his own code, he will call a method belonging to a class from the library, while maintaining control of the working flow. On the contrary, the framework calls your code, thus resulting in the “Inversion of Control”.

Internally, Java frameworks are heavily based on reflection capabilities.

Reflection or introspection is the capability of a program to inspect and change its structure and behavior at runtime. The Java Reflection API can view information about classes, interfaces, methods, fields, constructors, and annotations during Java program runtime. Frameworks do not need to know the names of inspected elements to do that, but may find them at runtime and alter the behavior of the program.

Due to their heavy usage inside frameworks and to the increase of the popularity of the frameworks during the last years, Java has also improved the performances of its reflection capabilities for the new versions [5].

In this article series we will set JPA, Hibernate and Spring Data JPA face to face, compare and contrast them and provide objective criteria about when to work with one or with another one.

Interested in learning how to program with Java or in upgrading your Java programming skills? Check out our trainings

Catalin Tudose
Java and Web Technologies Expert


[1] Christian Bauer, Gavin King, and Gary Gregory, Java Persistence with Hibernate, Second Edition. Manning, 2015
[2] Codd, E.F., “A relational model of data for large shared data banks.” [Communications of the ACM 13 (6): 377-87, 1970].
[3] Date, C.J., SQL and Relational Theory: How to Write Accurate SQL Code, 3rd edition. O’Reilly Media, 2015.
[4] Ramez Elmasri and Shamkant Navathe, Fundamentals of Database Systems. Pearson, 2016.
[5] Radu Şerban, Cătălin Tudose, Carmen Odubăşteanu, Java Reflection Performance Analysis Using Different JDKs, CSCS 18, 2011

Share the knowledge

Still have questions?
Connect with us
Thank you.
Your request has been received.
Thank you!
The form has been submitted successfully.