Skip to content

JPA — cheat sheet

Mandatory. Source: roadmap.md section "JPA".

  • ORM: Object-Relational Mapping — maps between objects in code and rows in a relational table, so you work with Java objects instead of hand-writing SQL for CRUD.
  • JPA vs Hibernate: JPA is a Java specification (interfaces/annotations) for ORM; Hibernate is the most popular implementation of that spec, and what actually runs underneath in Spring Boot by default. In practice: you write against JPA annotations, Hibernate does the work.

Wiring a database into a Spring project

  • Dependencies: spring-boot-starter-data-jpa + a driver (e.g. postgresql).
  • Connection config (URL/username/password/dialect) goes in application.properties.
  • Entity annotations:
    • @Entity — marks a class as a JPA-managed persistent entity (maps to a table).
    • @Id — marks the primary key field.
    • @GeneratedValue — tells JPA to auto-generate the id (e.g. auto-increment).
    • @Column — customizes the column mapping, e.g. @Column(columnDefinition = "TEXT") for unlimited-length text (needed for post title/content so they aren't truncated to a default VARCHAR(255)).
  • JpaRepository: Spring Data interface that gives you CRUD + paging/sorting for free just by extending it — no implementation needed.
  • Spring Data query methods: e.g. findByIsDraftFalseAndPublishedDateBefore(LocalDateTime now) — Spring generates the SQL from the method name/signature.
    • Why not findAll() + stream-filter instead: filtering in the DB means only the matching rows cross the network and the DB can use indexes; findAll() + filter pulls the entire table into memory just to throw most of it away — wasteful and doesn't scale.
  • @Transactional: wraps a method in a DB transaction — commits on success, rolls back on exception. Put it on service-layer methods doing multiple related writes, or that need a consistent view across lazily-loaded associations.
  • FetchType.LAZY vs EAGER:
    • LAZY loads the related entity/collection only when actually accessed. Better performance/less unneeded data, but needs an open persistence context when accessed later or you get a LazyInitializationException.
    • EAGER loads it immediately together with the parent.
    • Defaults: @ManyToOne/@OneToOne are EAGER by default, @OneToMany/@ManyToMany are LAZY by default. General rule: prefer LAZY, opt into EAGER only when you know you'll always need it.

DTOs

  • DTO (Data Transfer Object): a plain object used to move data across a boundary (API response, layer boundary), decoupled from the JPA entity.
  • Why: avoids exposing your DB structure directly over the API, lets you shape the same data differently per endpoint, and avoids serialization problems with entities directly (infinite recursion on bidirectional relations, LazyInitializationException on unfetched associations).