JPA and Hibernate Basics

What is ORM and why use it instead of plain JDBC?

ORM (Object-Relational Mapping) maps Java classes to tables and objects to rows, so you work with Product objects instead of writing SQL and reading ResultSet columns by hand.

  • Removes boilerplate: no manual mapping, connection and statement handling.
  • Gives you dirty checking, caching, lazy loading, cascading and optimistic locking for free.
  • Database-independent queries (JPQL) and generated SQL per dialect.
  • Cost: less control over SQL; you must understand what SQL it generates (N+1, extra updates).

What is the difference between JPA, Hibernate and Spring Data JPA?

What it isExample API
JPA (Jakarta Persistence)a specification: annotations and interfaces only@Entity, EntityManager, JPQL
Hibernatethe most popular implementation of JPA, plus extra featuresSession, @BatchSize, @DynamicUpdate
Spring Data JPAa Spring abstraction on top of JPA that generates repositoriesJpaRepository, derived queries, @Query

Stack: your code → Spring Data JPA → JPA API → Hibernate → JDBC → database. Since Jakarta EE 9 the package is jakarta.persistence.*, not javax.persistence.*.

What is the persistence context? How do EntityManager and Session relate?

The persistence context is the set of managed entity instances for one unit of work (usually one transaction). It works as a first-level cache and identity map: one row = one Java object inside it, and Hibernate tracks changes to those objects.

EntityManager is the JPA interface to the persistence context; Hibernate's Session extends it. Get the native API with entityManager.unwrap(Session.class).

Explain the entity lifecycle states.

StateMeaningHow you get there
Transient (new)plain object, not known to Hibernate, no rownew Product()
Managed (persistent)tracked by the persistence context; changes are flushed automaticallypersist(), find(), query results, merge() result
Detachedhas a row/id but the context is closed or clearedtransaction ends, detach(), clear(), serialization
Removedscheduled for DELETE at flushremove() on a managed entity

What is the difference between persist() and merge()? What does Spring Data save() do?

  • persist(e): makes a new object managed; the same instance becomes managed. Returns void. Throws if given a detached entity.
  • merge(e): copies the state of a detached (or new) object onto a managed instance and returns that managed copy; the argument stays detached.
  • Hibernate 6 deprecated save(), update() and saveOrUpdate(); use persist()/merge().
  • Spring Data save(e) calls persist if the entity is new (id null or @Version null) else merge. Always use the returned object.
Product detached = new Product(1L, "Laptop");      // id set: not new
Product managed = productRepository.save(detached); // merge -> SELECT + copy
System.out.println(managed == detached);            // false

find() vs getReference() (get() vs load())?

find() / findById()getReference() / getReferenceById()
SQLSELECT immediately (unless in the context)no SQL; returns a lazy proxy
Row missingreturns null / empty OptionalEntityNotFoundException on first access
Use forwhen you need the datasetting a foreign key: order.setUser(userRepo.getReferenceById(id))

Note: Hibernate's Session.load() is deprecated in Hibernate 6 in favour of getReference().

What are the rules for a JPA entity class?

  • Annotated with @Entity and has a primary key marked @Id (or @EmbeddedId).
  • Has a public or protected no-arg constructor (Hibernate instantiates it by reflection).
  • Should not be final, and its persistent methods should not be final, so Hibernate can create lazy proxies.
  • A top-level class; records cannot be entities (they are final and immutable) but are great as DTOs/projections.
@Entity
@Table(name = "products")
public class Product {
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Column(nullable = false, length = 120)
    private String name;

    private BigDecimal price;

    protected Product() {}               // for Hibernate
    public Product(String name, BigDecimal price) { this.name = name; this.price = price; }
}

Explain the @GeneratedValue strategies.

StrategyHow it worksNotes
IDENTITYauto-increment column (MySQL)INSERT must run immediately to get the id, so JDBC batch inserts are disabled
SEQUENCEdatabase sequence (PostgreSQL, Oracle)best performance; allocationSize (default 50) lets Hibernate assign ids in memory
TABLEa separate table simulates a sequenceslow (row locks); avoid
AUTOHibernate picks (SEQUENCE where supported, else a table)be explicit in production
UUIDGenerationType.UUID (JPA 3.1 / Hibernate 6.2+)good for distributed ids; larger index

What does spring.jpa.hibernate.ddl-auto do? What should production use?

ValueEffect
nonedo nothing (Spring Boot default for non-embedded databases)
validatecheck the schema matches the entities; fail at startup if not
updateadd missing tables/columns; never drops; can leave a messy schema
createdrop and create the schema at startup
create-dropcreate at startup, drop at shutdown (default for embedded H2)

Tip: In production use validate or none and manage the schema with Flyway or Liquibase migrations.