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

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

The second part of our article series on Object-relational Mapping Using JPA, Hibernate and Spring Data JPA. This time we look at persistence with JPA.


JPA application

We’ll write a JPA application to save an item in the database and retrieve it. The machine running the code has MySQL Release 8.0 installed and a database named CSCS.

Let’s start by installing and configuring JPA, Hibernate, and the other needed dependencies. The source code is under the control of Apache Maven. We declare these dependencies:

Listing 1 The Maven dependencies on Hibernate, JUnit Jupiter, and MySQL:


The hibernate-entitymanager module includes transitive dependencies on other modules we’ll need, such as hibernate-core and the JPA interface stubs.

We need the junit-jupiter-engine dependency to run the JUnit 5 tests, and the mysql-connector-java dependency, the official JDBC driver for MySQL.

We insert the persistence unit in our code. This one contains configuration settings, including here the persistence provider, information about the database to connect to, entity classes, SQL dialect to use, credentials, SQL formatting, and others. JPA applications need one or more persistence units.

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

The persistence unit

The persistence.xml file is located in resources/META-INF/. Its content looks like this:

Listing 2 The persistence.xml configuration file


HibernatePersistenceProvider</provider>        #1
<property name="javax.persistence.jdbc.driver"

value="com.mysql.cj.jdbc.Driver"/>           #2
<property name="javax.persistence.jdbc.url"    

value="jdbc:mysql://localhost:3306/CSCS"/>   #3
<property name="javax.persistence.jdbc.user"

value="root"/>                              #4
<property name="javax.persistence.jdbc.password"

value=""/>                                   #5
<property name="hibernate.dialect"             #6

<property name="hibernate.hbm2ddl.auto"    

value="create"/>                           #7

  • As JPA is only a specification, we need to indicate the vendor-specific PersistenceProvider implementation of the API. The persistence we define will be backed by a Hibernate provider. #1
  • We indicate the JDBC properties - driver #2, URL of the database #3, username #4, and password #5 to access it. The machine we are running the programs on has MySQL 8 installed and the access credentials are the ones from persistence.xml.
  • The Hibernate dialect is MySQL8 #6, as the database to interact with is MySQL Release 8.0.
  • Every time the program is executed, the database will be created from scratch #7. This is ideal for automated testing when we want to work with a clean database for every test run.

The persistent class

The application we implement has a persistent class, Item:

Listing 3 The Item class

@Entity #1
public class Item {

@Id #2
@GeneratedValue #3
private Long id;

private String info; #4

  • Persistent classes need the @Entity annotation #1, to indicate they correspond to a database table. If no table name is specified, this class will be mapped by default to a table called ITEM.
  • Persistent classes need an attribute annotated with @Id #2, to correspond to the primary key of the database table. This attribute will be mapped to a column named ID.
  • The @GeneratedValue annotation indicates the automatic generation of primary keys #3. Many strategies may be used here, depending on the database: identity fields, values obtained from a sequence, or a table.
  • Attributes will be mapped to columns in the table. As no column name is specified, info attribute #4 will be mapped by default to a column called INFO.

Saving and retrieving items

Let’s save a new Item to the database.

Listing 4 The ItemJPATest class

public class ItemJPATest {

    void saveRetrieveItem() {
        EntityManagerFactory emf =              

                    "cscs");                     #1

        try {
           EntityManager em =

               emf.createEntityManager();        #2
           em.getTransaction().begin();          #3
           Item item = new Item();               #4
           item.setInfo("Item");                #4
           em.persist(item);                    #5
           em.getTransaction().commit();         #6
           em.close();                           #7

        } finally {
            emf.close();                        #8


  • We need an EntityManagerFactory to access the database #1. This factory corresponds to the persistence unit that we have previously defined.
  • Create an EntityManager and start a new database session #2.
  • Get access to the standard transaction API and begin a transaction #3.
  • Create a new instance of the Item class, and set its info property #4.
  • The transient instance becomes persistent on the side of the persistence context #5.
  • Commit the transaction #6. A new row is inserted in the ITEM table. Access to the database must be transactional, even if it is read-only.
  • As we created an EntityManager, we must close it #7.
  • As we created an EntityManagerFactory, we must close it #8.
  • There is no SQL code and no JDBC usage in the JPA application. There are no CRUD (create, read, update, delete) operations inside the Java code, but only working object-oriented way, with classes, objects, and methods. The translation to each SQL dialect is made by the ORM which also addresses portability.

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

Nadal masz pytania?
Połącz sięz nami