JDBC vs Hibernate vs JPA vs Spring Data JPA
Four Names, Four Layers
Beginners often mix these up. They are layers stacked on top of each other:
Your code (ProductService)
|
v
Spring Data JPA -> interface ProductRepository extends JpaRepository<Product, Long>
| (generates repository code for you)
v
JPA (Jakarta Persistence 3.1) -> the STANDARD API: @Entity, EntityManager, JPQL
|
v
Hibernate ORM 6 -> the IMPLEMENTATION of JPA (generates SQL, caching, dirty checking)
|
v
JDBC -> low-level Java API that sends SQL to the database
|
v
MySQL / PostgreSQL / H2 driver -> databaseComparison
| What it is | You write | Package | |
|---|---|---|---|
| JDBC | Low-level Java API for SQL | SQL strings, ResultSet loops | java.sql |
| JPA | A specification (rules + interfaces), no code that runs by itself | Annotations, EntityManager calls, JPQL | jakarta.persistence |
| Hibernate | The most popular JPA implementation, plus extra features | Same as JPA (optionally Hibernate-only APIs) | org.hibernate |
| Spring Data JPA | Spring library on top of JPA that removes repository boilerplate | Repository interfaces only | org.springframework.data.jpa |
Note: JPA used to be called Java Persistence API (javax.persistence). Since Jakarta EE 9 it is Jakarta Persistence and the package is jakarta.persistence. Spring Boot 3 and Hibernate 6 use only the new jakarta.* package — old tutorials with javax.persistence will not compile.
Same Task at Each Layer
Loading one product by id:
// JDBC: you write everything
try (PreparedStatement ps = conn.prepareStatement("select id, name, price from product where id = ?")) {
ps.setLong(1, 42L);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
product = new Product(rs.getLong("id"), rs.getString("name"), rs.getBigDecimal("price"));
}
}
}
// JPA (Hibernate underneath): one call, SQL generated
Product product = entityManager.find(Product.class, 42L);
// Spring Data JPA: you only declare an interface
Optional<Product> product = productRepository.findById(42L);Other JPA Implementations
Because JPA is a standard, other implementations exist: EclipseLink (the reference implementation) and OpenJPA. Spring Boot uses Hibernate by default, and almost every job posting that says "JPA" means Hibernate.
Tip: Write code against the jakarta.persistence API wherever possible. Use Hibernate-specific APIs (org.hibernate.*) only when you need a feature JPA does not have.