MGTEKENINGENSETmichaelgoldman.dev

BLAD 03Projecten

ENNLCV
BLADEN
ENNLCV
BLAD 03 · TEKENINGENREGISTER

DETAILBLAD 03.3 — P-03

Recipe Book

Recipes with ordered steps and ingredients. Part 2 of the series: JPA done deliberately, with the API contract written before any code.

REPOSITORY OP GITHUB

JUL 2026 · DEEL 2 VAN DE SERIE

FIG. 1 — DESIGN-FIRST FLOW
openapi.yamlOpenAPI 3.1
generates
API interfaces & DTOsgenerated at build
DTOs
Controllersproblem+json errors
mapper
Recipe aggregateJPA · Hibernate
JPA
PostgreSQL 185 Flyway migrations

SPECIFICATIE

AGGREGATE
Recipe is the aggregate root: steps and ingredients are reached, saved and deleted only through it — cascade ALL and orphanRemoval in JPA, ON DELETE CASCADE in the schema.
PERSISTENCE
JPA/Hibernate through a hand-written EntityManager repository, no Spring Data. SEQUENCE ids with allocationSize 50, id-based equals, open-in-view off.
CONCURRENCY
@Version optimistic locking: a concurrent edit gets 409 Conflict as RFC 9457 problem details.
QUERIES
The list reads a RecipeSummary projection — name, description and counts — instead of loading whole aggregates.
INTEGRITY
CHECK constraints, case-insensitive unique names and deferrable unique step order, across 5 Flyway migrations on PostgreSQL 18.
API
Design-first OpenAPI 3.1: openapi-generator builds the DTOs and API interfaces from docs/api/openapi.yaml; the mappers are hand-written.
TESTING
109 tests, written test-first: unit, web slice, repository and end-to-end on Testcontainers, plus ArchUnit rules that enforce the layering.
FIG. 2 — AGGREGATE
Recipeaggregate root · @Version
cascade ALL · orphanRemoval
Stepordered · deferrable unique
Ingredientquantity > 0 · unique name

REV. NOTE Re-ordering steps saves in one transaction thanks to deferrable unique constraints.