JPA and Hibernate for Dummies
When working with Java you’ll eventually come across the terms JPA (Java Persistence API) and Hibernate.
TLDR
JPA (Java Persistence API) is a specification โ a set of interfaces and annotations that describes what an ORM tool should do.
Hibernate is the most popular implementation of that specification.
You write your code against the JPA interfaces. Hibernate (or another provider) does the actual work under the hood.
JPA (Java Persistence API) aka Jakarta Persistence
JPA is a Java specification that describes what an ORM (Object-Relational Mapping) tool should do.
It was renamed to Jakarta Persistence in 2019 due to trademark restrictions. (Hello Oracle ๐)
It provides annotations like @Entity, @Id, @Table, and @Column that can be added to regular Java classes.
import jakarta.persistence.*;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "full_name")
private String name;
// Getters and setters...
}
These annotations are used to map a database table and its entries to Java objects.
This allows us developers to interact with the underlying database without having to write SQL.
Here is an example using the EntityManager to create a new Employee entry in the database.
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
// Create a new entity
Employee emp = new Employee();
emp.setName("Jane Doe");
// Save to database
em.persist(emp);
em.getTransaction().commit();
em.close();
JPA vs Hibernate
It is crucial to understand that JPA is only a set of interfaces. To use JPA we need an ORM framework like Hibernate that implements the specifications.
Besides Hibernate there are other frameworks like EclipseLink and OpenJPA but Hibernate is the most popular.
In Practice: Spring Boot
In modern Java development, you rarely set up JPA or Hibernate directly. Spring Boot auto-configures everything for you via Spring Data JPA.
You declare a repository interface and Spring generates the implementation at startup:
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
// Spring generates: findAll(), findById(), save(), delete(), ...
}
Under the hood, Spring Data JPA uses the JPA EntityManager, and Hibernate provides the actual JPA implementation. The layers stack like this:
Your Code
โ
Spring Data JPA (convenience layer)
โ
JPA / EntityManager (standard interfaces)
โ
Hibernate (actual implementation)
โ
JDBC / Database
So when you call employeeRepository.save(emp), it flows all the way down to Hibernate, which generates the SQL and sends it to the database.