Spring Data JPA & Hibernate
Spring Data JPA lets you interact with databases using Java objects instead of writing SQL. Hibernate handles the translation. Together they make database operations simple and safe.
JPA = the diplomatic rulebook (what messages can be sent, the protocol).
Hibernate = the actual translator who knows the language (implements JPA, translates Java to SQL).
Spring Data JPA = your assistant who writes the diplomatic messages for you based on method names, so you don't have to write them yourself.
| Layer | What it is | Role |
|---|---|---|
| JPA | Java Persistence API โ a specification (interface) | Defines the rules: @Entity, @Id, @OneToMany, etc. |
| Hibernate | JPA implementation (ORM framework) | Translates Java objects โ SQL queries |
| Spring Data JPA | Spring abstraction over Hibernate | Auto-generates CRUD + custom queries from method names |
| Annotation | Purpose |
|---|---|
@Entity | Marks class as a JPA entity (mapped to a table) |
@Table | Customise table name and constraints |
@Id | Marks the primary key field |
@GeneratedValue | Auto-generate primary key (IDENTITY = DB auto-increment) |
@Column | Customise column (name, nullable, unique, length) |
@Transient | Field is NOT mapped to any column |
One-to-Many: One Course has Many Students
Eager Loading = "Get everything upfront." Like downloading all movies immediately when you open the app.
@EntityGraph or JPQL JOIN FETCH to load related data in one query when you know you'll need it.JOIN FETCH in specific queries that need the relationship.JPA (Java Persistence API) is a specification โ a set of interfaces and annotations that define how Java objects should be mapped to relational databases. JPA itself is not a library, it's just a standard.
Hibernate is an implementation of the JPA specification. It's the most popular ORM (Object Relational Mapper) for Java. When Spring Boot sets up JPA, it uses Hibernate under the hood by default.
@OneToMany โ One entity has a collection of another. E.g., one Course has many Enrollments. Placed on the "one" side.
@ManyToOne โ Many entities relate to one entity. E.g., many Enrollments belong to one Course. Placed on the "many" side. This side owns the relationship (holds the foreign key column in the database).
Lazy loading means related entities are not loaded from the database until they're accessed in code. This is the default for @OneToMany collections.
The N+1 problem occurs when you load N entities (1 query) and then access a lazy-loaded collection on each one in a loop โ causing N additional queries. E.g., loading 100 courses and then accessing each course's enrollments = 1 + 100 = 101 queries!
Fix: Use JPQL JOIN FETCH to load the relationship in one query, or use @EntityGraph to specify what to load eagerly for a specific query.
- create โ drop and re-create schema on every startup (lose all data)
- create-drop โ create on startup, drop on shutdown (for tests)
- update โ update schema if entities change but don't drop existing data (development)
- validate โ validate that schema matches entities but don't change it (production)
- none โ do nothing, manage schema manually (recommended for production)
Cascading defines what happens to related entities when an operation is performed on the parent. cascade = CascadeType.ALL means all operations (PERSIST, MERGE, REMOVE, REFRESH) are cascaded to the children.
Example: If you delete a Course with CascadeType.ALL, all its Enrollments are also deleted automatically.
Common types: ALL, PERSIST (save children when saving parent), REMOVE (delete children when deleting parent), MERGE (update children when updating parent).