JPA - Obtaining a JPA Database Connection

Overview

A connection to a database is represented by an EntityManager instance, which also provides functionality for performing operations on a database. Many applications require multiple database connections during their lifetime. For instance, in a web application, it is common to establish a separate database connection, using a separate EntityManager instance, for every HTTP request.

The main role of an EntityManagerFactory instance is to support instantiation of EntityManager   instances. An EntityManagerFactory is constructed for a specific database, and by managing resources efficiently (e.g. a pool of sockets), provides an efficient way to construct multiple EntityManager instances for that database.

Operations that modify the content of a database require active transactions. Transactions are managed by an EntityTransaction instance obtained from the EntityManager.

An EntityManager instance also functions as a factory for Query instances, which are needed for executing queries on the database.

Step 1: Obtaining an EntityManagerFactory

Obtaining an EntityManager instance consists of two steps. First, we need to obtain an instance of EntityManagerFactory that represents the relevant database and then we can use that factory instance to get an EntityManager instance.
JPA requires the definition of a persistence unit in an XML file in order to be able to generate an EntityManagerFactory.

persistence.xml file

In JPA, the persistence.xml file is the central piece of configuration. That makes it one of the most important files of your persistence layer.
<persistence
    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"
 version="2.1">
    <persistence-unit name="PERSISTENCE">
        <description> Hibernate JPA Configuration Example</description>
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>net.javaguides.hibernate.entity.Student</class>
        <properties>
            <property name="javax.persistence.jdbc.driver"
    value="com.mysql.cj.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url"
    value="jdbc:mysql://localhost:3306/hibernate_db" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password"
    value="root" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
        </properties>
    </persistence-unit>
</persistence>
Let's create an instance of EntityManagerFactory class using Persistence class.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PERSISTENCE");
  • Persistence - The Persistence is a bootstrap class which is used to obtain an EntityManagerFactory interface.
  • createEntityManagerFactory() method - The role of this method is to create and return an EntityManagerFactory for the named persistence unit. Thus, this method contains the name of the persistence unit passed in the Persistence.xml file.

Step 2: Obtaining an EntityManager

Once we have an EntityManagerFactory we can easily obtain an EntityManager instance:
EntityManager entityManager = entityManagerFactory.createEntityManager();
  • EntityManager - An EntityManager is an interface
  • createEntityManager() method - It creates new application-managed EntityManager
The EntityManager instance represents a connection to the database. When using JPA, every operation on a database is associated with an EntityManager. Further, in a multithreaded application, every thread usually has its own EntityManager instance while at the same time sharing a single application-wide EntityManagerFactory.

Step 3: Using an EntityTransaction

Operations that modify database content, such as a store, update, and delete should only be performed within an active transaction.

Begin the Transaction

Given an EntityManager, entityManager, it is very easy to begin a transaction:
entityManager.getTransaction().begin();
  • getTransaction() method - This method returns the resource-level EntityTransaction object.
  • begin() method - This method is used to start the transaction.
There is a one to one relationship between an EntityManager instance and it's associated EntityTransaction instances that the getTransaction() method returns.

Closing the Transaction

When a transaction is active you can invoke EntityManager methods that modify the database content, such as persist and remove. Database updates are collected and managed in memory and applied to the database when the transaction is committed:
entityManager.getTransaction().commit();

Step 4: Closing EntityManagerFactory and EntityManager Resources

The EntityManagerFactory is also used to close the database once we are finished using it:
entityManagerFactory.close();
When the connection to the database is no longer needed the EntityManager can be closed:
entityManager.close();

Complete Example - Let's Put Together

private static void insertEntity() {
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PERSISTENCE");
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    entityManager.getTransaction().begin();

    Student student = new Student("Ramesh", "Fadatare", "[email protected]");
    entityManager.persist(student);
    entityManager.getTransaction().commit();
    entityManager.close();
    entityManagerFactory.close();
}

Comments