Java Persistence API (JPA) is a Java application programming interface specification that describes the management of relational data in applications using Java Standard Edition, and Java Enterprise Edition. Various frameworks like Hibernate, EclipseLink, and Apache OpenJPA provide object-relational mapping according to the JPA standards. This tutorial shows you to develop a simple Java Persistence API (JPA) Hello World project using Hibernate framework and MySQL database.

Requirements


Create Database and Table in MySQL

For the hello world project, let’s create a database named “javahelps” and a table named “student” in MySQL.

CREATE DATABASE IF NOT EXISTS javahelps;

CREATE TABLE javahelps.student (
student_id INT NOT NULL,
student_name VARCHAR(64) NOT NULL,
student_age INT NOT NULL,
PRIMARY KEY (student_id)
);

Create a New JPA Hello World Project

Step 1:
Create a new Maven project in IntelliJ Idea with group id: com.javahelps.helloworld and artifact id: jpa-hibernate-hello-world.

Step 2:
Add the following dependencies to the pom.xml file. Note that the latest Hibernate requires only the core library and the JDBC connector for your database. Since we are using MySQL, the mysql-connector-java library is used.

<!-- Hibernate Dependency -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>

<!-- MySQL JDBC Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.java.version}</version>
</dependency>

Not all newer versions of libraries guarantee backward compatibility with previous versions. Therefore, I recommend using the same version of the library as in the following pom.xml for your first run. Once you get the code working, search for the artifact ids in the public Maven Repository and use the latest version of the dependencies in your production code. Please note that older versions may have unpatched vulnerabilities and make your code vulnerable to attacks. I will try my best to keep the articles up to date but it is impossible for me to keep track of all libraries used in Java Helps. If you find any breaking changes in newer versions, please comment below.

After adding the dependencies, the pom.xml should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<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>com.javahelps.helloworld</groupId>
<artifactId>jpa-hibernate-hello-world</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hibernate.version>6.1.5.Final</hibernate.version>
<mysql.connector.java.version>8.0.31</mysql.connector.java.version>
</properties>

<dependencies>
<!-- Hibernate Dependency -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>

<!-- MySQL JDBC Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.java.version}</version>
</dependency>
</dependencies>
</project>

Create A New JPA Entity

Create a new class named Student with the following code. As you can see, Java Persistent API annotations are used to mark this class as a JPA Entity. I hope the annotations are self-explanatory. If you have any questions regarding the entity class definition, please comment below.

Note that the Java 17 Records cannot be used as a JPA entity because JPA Entity requires a default (no-arg) constructor.

package com.javahelps.helloworld;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "student")
public class Student {
@Id
@Column(name = "student_id", unique = true)
private int id;

@Column(name = "student_name", nullable = false)
private String name;

@Column(name = "student_age", nullable = false)
private int age;

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;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return id "\t" name "\t" age;
}
}

Add JPA Persistence Configuration

Create a new folder named META-INF in the src/main/resources folder. Inside the META-INF folder, create a new file named persistence.xml with the following content. Replace the JDBC URL and MySql credentials according to your database.

The JDBC URL in the following code is affected by the code highlighter used in this website. The actual path must look like this:

Compare the project structure with the screenshot shared at the end of this article to make sure that you have created the persistence.xml in the right path.

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://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"
             version="2.0">
    <persistence-unit name="JavaHelps" transaction-type="RESOURCE_LOCAL">
        <!-- Persistence provider -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <!-- Entity classes -->
        <class>com.javahelps.helloworld.Student</class>

        <properties>
            <!-- The JDBC URL to the database instance -->
            <property name="jakarta.persistence.jdbc.url"
                      value="jdbc:mysql://localhost:3306/javahelps?useSSL=false&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC"/>

            <!-- The database username -->
            <property name="jakarta.persistence.jdbc.user" value="root"/>

            <!-- The database password -->
            <property name="jakarta.persistence.jdbc.password" value="root"/>
        </properties>
    </persistence-unit>
</persistence>

Create A Data Access Object (DAO) Class

Data Access Object (DAO) pattern is commonly used with Database access. Even though I implement a separate class similar to the DAO pattern, do not take this as the complete example of the DAO pattern. Usually, the DAO pattern requires an interface and an implementation but considering the scope of this article, I haven’t implemented a complete DAO pattern here.

Create a new class named StudentDao with the following code. Pay attention to the TODO comments. There is no problem in throwing a RuntimeException in a Hello, World! project, but in a production code, you must handle the exceptions properly.

package com.javahelps.helloworld;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.RollbackException;

import java.util.List;

public class StudentDao {

private final EntityManagerFactory entityManagerFactory;

public StudentDao(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}

public List<Student> findAll() {
// Create a new EntityManager
EntityManager manager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = null;
List<Student> students;
try {
// Get a transaction
transaction = manager.getTransaction();
// Begin the transaction
transaction.begin();

// Get all students from the table.
// Note that the SQL is selecting from "Student" entity not the "student" table
students = manager.createQuery("SELECT stu FROM Student stu", Student.class)
.getResultList();

// Commit the transaction
transaction.commit();
} catch (RollbackException ex) {
// Commit failed. Rollback the transaction
if (transaction != null) {
transaction.rollback();
}
// TODO: Decide how you want to handle this exception.
// Since this is a hello world project, we throw the exception.
throw new RuntimeException(ex);
} finally {
// Close the EntityManager
manager.close();
}
return students;
}

public void create(Student student) {
// Create a new EntityManager
EntityManager manager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = null;

try {
// Get a transaction
transaction = manager.getTransaction();
// Begin the transaction
transaction.begin();
// Save the student object
manager.persist(student);
// Commit the transaction
transaction.commit();
} catch (RollbackException ex) {
// Commit failed. Rollback the transaction
if (transaction != null) {
transaction.rollback();
}
// TODO: Decide how you want to handle this exception.
// Since this is a hello world project, we throw the exception.
throw new RuntimeException(ex);
} finally {
// Close the EntityManager
manager.close();
}
}

public void update(Student newStudentWithSameId) {
// Create a new EntityManager
EntityManager manager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = null;

try {
// Get a transaction
transaction = manager.getTransaction();
// Begin the transaction
transaction.begin();
// First find the student to update the object
// You cannot insert a new student with the same id since it will be treated as a duplicate entry
Student student = manager.find(Student.class, newStudentWithSameId.getId());
if (student != null) {
// Note that the id cannot be changed
student.setName(newStudentWithSameId.getName());
student.setAge(newStudentWithSameId.getAge());
// Save the changes
manager.persist(student);
}
// Commit the transaction
transaction.commit();
} catch (RollbackException ex) {
// Commit failed. Rollback the transaction
if (transaction != null) {
transaction.rollback();
}
// TODO: Decide how you want to handle this exception.
// Since this is a hello world project, we throw the exception.
throw new RuntimeException(ex);
} finally {
// Close the EntityManager
manager.close();
}
}

public void delete(int id) {
// Create a new EntityManager
EntityManager manager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = null;

try {
// Get a transaction
transaction = manager.getTransaction();
// Begin the transaction
transaction.begin();
// First find the student
Student student = manager.find(Student.class, id);
if (student != null) {
// Remove the student
manager.remove(student);
}
// Commit the transaction
transaction.commit();
} catch (RollbackException ex) {
// Commit failed. Rollback the transaction
if (transaction != null) {
transaction.rollback();
}
// TODO: Decide how you want to handle this exception.
// Since this is a hello world project, we throw the exception.
throw new RuntimeException(ex);
} finally {
// Close the EntityManager
manager.close();
}
}

public void deleteAll() {
// Create a new EntityManager
EntityManager manager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = null;

try {
// Get a transaction
transaction = manager.getTransaction();
// Begin the transaction
transaction.begin();
// Delete all students
manager.createQuery("DELETE FROM Student")
.executeUpdate();
// Commit the transaction
transaction.commit();
} catch (RollbackException ex) {
// Commit failed. Rollback the transaction
if (transaction != null) {
transaction.rollback();
}
// TODO: Decide how you want to handle this exception.
// Since this is a hello world project, we throw the exception.
throw new RuntimeException(ex);
} finally {
// Close the EntityManager
manager.close();
}
}
}

Create/Modify Main Class

Modify the Main class as shown below. In the main method, we create three student objects and execute the CRUD operations using the StudentDao created in the previous step. Pay attention to the Fixme comment. At the end of the method, all entities are deleted from the student table to avoid violating primary key constraints when running this code multiple times.

package com.javahelps.helloworld;

import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

import java.util.List;

public class Main {

public static void main(String[] args) {
// Create an EntityManagerFactory when you start the application.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("JavaHelps");
// Create the DAO object
StudentDao dao = new StudentDao(entityManagerFactory);

// Create some students to play around
Student alice = new Student();
alice.setId(1);
alice.setName("Alice");
alice.setAge(22);

Student bob = new Student();
bob.setId(2);
bob.setName("Bob");
bob.setAge(20);

Student charlie = new Student();
charlie.setId(3);
charlie.setName("Charlie");
charlie.setAge(25);

// Create the Students
dao.create(alice);
dao.create(bob);
dao.create(charlie);


// Update the age of Bob using the id
Student newBob = new Student();
newBob.setId(2); // You must use the same id as existing entity
newBob.setName("Bob");
newBob.setAge(25);
dao.update(newBob);

// Delete the Alice from database
dao.delete(1);

// Print all the Students
List<Student> students = dao.findAll();
if (students != null) {
for (Student student : students) {
System.out.println(student);
}
}

// Fixme: Deleting all students to avoid duplicate entry errors when running this code multiple times
dao.deleteAll();

// Never forget to close the entityManagerFactory
entityManagerFactory.close();
}
}

Run the Project

Run the main class and check the outputs.

You must see the Bob and Charlie printed in the terminal. To avoid the overwhelming amount of Hibernate logs from distracting you, check on: How to Disable Hibernate Logs in the Output.

You can download the complete source code of this project along with all the resources from our Git Hub repository.

Have you found this article useful? Please let me know below in the comments. Knowing someone found my articles useful motivates me to write more. Also, comment below if you face any issues with following this article or getting it working. I will try my best to help you resolve the problem. The Java Helps community is also willing to help each other and grow together.

Share.
Exit mobile version