1---2name: database-patterns3description: Database patterns for Java Spring — R2DBC (reactive), JPA/Hibernate (servlet), PostgreSQL, MySQL, connection pooling (HikariCP/r2dbc-pool), Flyway migrations, and query optimization. Use when writing @Entity or R2DBC models, creating Repository interfaces, writing @Query methods, planning Flyway migrations, tuning connection pools, or reviewing SQL performance. Includes scripts/validate-migration.sh for migration file validation.4---56# Database Patterns78## Stack Decision910| Criterion | JPA / HikariCP | R2DBC / R2DBC Pool |11|-----------|---------------|-------------------|12| Runtime | Spring MVC (blocking) | Spring WebFlux (reactive) |13| Repository | `JpaRepository` | `ReactiveCrudRepository` |14| Transaction | `@Transactional` | `@Transactional` + `TransactionalOperator` |15| PG driver | `org.postgresql:postgresql` | `org.postgresql:r2dbc-postgresql` |16| MySQL driver | `com.mysql.cj.jdbc.Driver` | `io.asyncer:r2dbc-mysql` |1718## Engine Differences1920| Aspect | PostgreSQL | MySQL |21|--------|-----------|-------|22| PK strategy | `GENERATED ALWAYS AS IDENTITY` / `SEQUENCE` | `BIGINT UNSIGNED AUTO_INCREMENT` |23| JPA `@GeneratedValue` | `SEQUENCE` + `@SequenceGenerator` | `IDENTITY` |24| Strings | `text` (no storage diff vs varchar) | `VARCHAR(n)` + `utf8mb4` required |25| Timestamps | `timestamptz` (always TZ-aware) | `DATETIME(3)` (store in UTC) |26| Covering index | `INCLUDE (col)` | List all cols in key (no INCLUDE) |27| Partial index | `WHERE` clause on index | Not supported (use composite) |28| Concurrent index | `CREATE INDEX CONCURRENTLY` | `ALGORITHM=INPLACE, LOCK=NONE` |29| Transactional DDL | Yes | No (implicit commit) |30| Default isolation | `READ_COMMITTED` | `REPEATABLE_READ` (gap locks) |3132## Critical Rules (Both Engines)33341. **`@SQLRestriction` not `@Where`** — Hibernate 6+352. **`FetchType.LAZY` always** — JOIN FETCH / `@EntityGraph` at call site363. **No `.block()` in reactive** — use R2DBC on WebFlux374. **`open-in-view: false`** — always disable385. **Parameterized queries only** — never concatenate user input396. **Index all FK columns**407. **Pool size = `vCPU * 2 + 1`** (SSD); smaller pools outperform oversized418. **DTO projections for read-only** — skip entity lifecycle overhead4243## Migration Safety (Expand-Contract)44451. **Expand** — add nullable column; code writes both old+new462. **Migrate** — backfill in batches (1000 rows), not single UPDATE473. **Contract** — add NOT NULL / drop old column in separate deploy4849**Always safe**: add nullable column, index (CONCURRENTLY/INPLACE), add table.50**Never in prod**: DROP without expand-contract, ALTER to smaller type, TRUNCATE.5152## Verification Checklist5354- [ ] No `@Data` on entities; use `@Getter` + `@NoArgsConstructor(PROTECTED)` + builder55- [ ] `@EntityGraph` / JOIN FETCH for known N+1 paths56- [ ] DTO projections for read-only queries57- [ ] `@Transactional(readOnly = true)` on query methods58- [ ] HikariCP leak detection enabled in non-prod59- [ ] Migrations follow `V{n}__{description}.sql` naming60- [ ] Large table changes use online DDL or batch strategy61- [ ] Migration tested with Testcontainers6263## References6465| File | Contents |66|------|----------|67| [postgresql.md](references/postgresql.md) | Schema, indexing (B-tree/GIN/GiST/BRIN/covering/partial), UPSERT, keyset pagination, SKIP LOCKED, RLS, JPA config, R2DBC config, pool sizing, Flyway |68| [mysql.md](references/mysql.md) | Schema, indexing (covering without INCLUDE, invisible, generated columns), utf8mb4, JPA config, R2DBC asyncer driver, pool sizing, Flyway |69| [jpa-hibernate.md](references/jpa-hibernate.md) | Entity design, N+1 prevention (EntityGraph/JOIN FETCH/DTO projections), HikariCP config, pagination (offset + cursor), batch writes, specifications |70| [r2dbc.md](references/r2dbc.md) | ReactiveCrudRepository, R2dbcEntityTemplate, DatabaseClient, reactive transactions, pool config, Testcontainers testing |71| [migrations.md](references/migrations.md) | Flyway naming, expand-contract, safety rules, large table strategies (PG vs MySQL), Testcontainers validation |7273## Related Skills7475- **summer-data** — R2DBC converters, audit_log/outbox_events DDL, AuditTableValidator76- **spring-webflux-patterns** — JPA (MVC) or R2DBC (WebFlux) stack selection77- **redis-patterns** — Cache-aside to reduce DB load78- **testing-workflow** — Testcontainers for DB integration tests, @DataR2dbcTest/@DataJpaTest