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.
Apache Maven (Not necessary if you are not going to build the project outside of the IDE)
MySQL
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.
<!-- 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:
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.
@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:
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.
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.
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.