Lesson 1 / 25

Why ORM, and What JPA and Hibernate Are

Explain the object-relational mismatch and the roles of JPA, Hibernate and Spring Data JPA.

Bridging objects and tables

Java applications model data as objects with references, inheritance and collections, while relational databases store rows in tables linked by foreign keys. The differences, called the object-relational impedance mismatch, include identity (object identity vs primary keys), associations (references vs foreign keys and join tables), inheritance (which tables have no direct equivalent of) and navigation (walking an object graph vs running joins). Writing JDBC code by hand means mapping every column to every field, managing connections and SQL strings, and remembering which objects changed. An object-relational mapper (ORM) automates this. Jakarta Persistence (JPA), formerly the Java Persistence API, is the specification: annotations such as @Entity, the EntityManager API and the JPQL query language, now in the jakarta.persistence package. Hibernate ORM is the most widely used implementation of JPA, with many extra features; EclipseLink is another. Spring Data JPA sits on top, generating repository implementations so you write interfaces instead of boilerplate data-access classes.

Layers of Java persistence

Your code talks to Spring Data and the JPA API; Hibernate implements JPA and uses JDBC to talk to the database.

Stacked horizontal layers from top to bottom: an application layer, a repository layer, an API layer, an implementation layer and a driver layer above a database cylinder.
Figure 1.1 — Application, Spring Data JPA, JPA, Hibernate, JDBC and the database.

JDBC by hand versus a JPA entity

The ORM generates the SQL and the mapping code.

// plain JDBC: manual SQL and manual mapping
try (var ps = conn.prepareStatement("SELECT id, name, email FROM customers WHERE id = ?")) {
    ps.setLong(1, id);
    try (var rs = ps.executeQuery()) {
        if (rs.next()) {
            customer = new Customer(rs.getLong("id"), rs.getString("name"), rs.getString("email"));
        }
    }
}

// JPA: map once, then work with objects
@Entity
@Table(name = "customers")
public class Customer {
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private String name;
    private String email;
    protected Customer() { }                 // JPA needs a no-arg constructor
    // getters, domain methods ...
}

Customer c = entityManager.find(Customer.class, id);   // Hibernate writes the SELECT

An ORM does not replace SQL knowledge

Hibernate writes SQL for you, but you still need to understand joins, indexes and transactions to keep it fast and correct. Most ORM performance problems are SQL problems in disguise.

Quick check: What is the relationship between JPA and Hibernate?

  • JPA is the specification; Hibernate is an implementation of it
  • They are competing databases
  • Hibernate is the specification; JPA implements it
  • JPA is a Spring module
Answer

JPA is the specification; Hibernate is an implementation of it — Jakarta Persistence defines the API; Hibernate ORM implements it and adds extra features.