Skip to main content

jpa-hibernate-performance

Specializes in Java Persistence performance (JPA/Hibernate) based on High-Performance Java Persistence (Vlad Mihalcea). Covers JDBC batching, the N+1 query problem and fetch strategies (JOIN FETCH, EntityGraph), FlushOperationQueue and ActionQueue, dirty checking, first- and second-level caching (read-through/nonstrict-read-write), optimistic and pessimistic locking, efficient pagination (keyset vs OFFSET), transactions and isolation, and per-database SQL tuning (EXPLAIN, execution plans).

Quellinformationen

Repository
dandgabr/Coacus
Letzte Quellaktivität
20. September 2026 um 03:33
Erkannte Sprache von SKILL.md
Englisch
Sterne
4
Forks
3

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
5 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
jpa-hibernate-performance
description
Specializes in Java Persistence performance (JPA/Hibernate) based on High-Performance Java Persistence (Vlad Mihalcea). Covers JDBC batching, the N+1 query problem and fetch strategies (JOIN FETCH, EntityGraph), FlushOperationQueue and ActionQueue, dirty checking, first- and second-level caching (read-through/nonstrict-read-write), optimistic and pessimistic locking, efficient pagination (keyset vs OFFSET), transactions and isolation, and per-database SQL tuning (EXPLAIN, execution plans).
# AI Skill: High Performance in Java Persistence (JPA/Hibernate) This skill guides the artificial intelligence to design the Java/JPA persistence layer with a focus on performance, based on *High-Performance Java Persistence* (Vlad Mihalcea), covering raw JDBC, JPA, and Hibernate. --- ## 🧱 1. Persistence Layer Architecture - **Deliberate choice of tool**: raw JDBC batching for ETL/bulk; JPA+Hibernate for domain OLTP; native SQL/projections for analytical queries — **do not force an ORM on everything**. - **Access stereotypes**: domain entities (aggregates with short transactions), DTO projections (read queries), value types (immutable embeddables). - **Short transactions**: the transaction scope equals the smallest atomic unit; never run UI or remote calls inside an open transaction. --- ## 🔥 2. The N+1 Problem and Fetch Strategies ### Diagnosis - **N+1**: one query for the root entity plus N lazy queries while navigating associations; detect it with `hibernate.generate_statistics=true`, `nullSafeGet`/SQL log, and hydration tests. ### Mitigations (in order of preference) 1. **JOIN FETCH** in JPQL: `SELECT a FROM Author a JOIN FETCH a.books WHERE a.id = :id` — a single round-trip fetch. 2. **@EntityGraph**: declarative definition of the fetch plan per use case (without polluting queries). 3. **`@_BATCH(size)` / `hibernate.default_batch_fetch_size`**: turn N queries into N/size `IN (...)` queries — the best balance for arbitrary associations. 4. **`@Fetch(FetchMode.SUBSELECT)`**: for collections accessed in bulk within the same transaction. 5. **`@BatchSize`** on lazy collections; `@LazyCollection(LazyCollectionOption.EXTRA)` for count-only. ### Rules - `FetchType.LAZY` on **every** association (the safe default); a UNI-side `@ManyToOne(optional=false)` may be EAGER with justification. - Never use "open session in view" in production — the classic villain of N+1 and long transactions. - For large many-to-many, prefer **two unilateral bidirectional** associations with an extra `@LazyCollection(ExtraLazyType)`. Access them through a DTO when the write model does not need the collection. --- ## 📦 3. Write-Behind, Flush, and Batching ### ActionQueue and Flush Order - Hibernate orders operations in the `ActionQueue` (inserts → updates → collection removes → deletions), already designed for FK/UNIQUE; understand the order in multi-entity transactions. - `FlushModeType.AUTO` flushes on queries "[flush before a query that may touch pending data]"; use `COMMIT` for read-only hot paths and control the flush manually (`em.flush()`). ### JDBC Batching - Enable: `hibernate.jdbc.batch_size` (30–50 typical), `order_inserts=true`, `order_updates=true`, `batch_versioned_data=true`. - **Driver requirement**: `rewriteBatchedStatements` (MySQL), `reWriteBatchedInserts` (PostgreSQL) for a real batch on the wire. - **IDENTITY disables insert batching** (Hibernate needs the generated id); prefer `SEQUENCE` (with `allocationSize` 50+) or `TABLE` with a pooler (pooled-lo). - Bulk: `JPQL/HQL bulk update+delete` (they bypass the persistence context), `StatelessSession`, or `Session.doWork` with direct JDBC for large volumes. ### Dirty Checking and State - Default dirty checking scans the context's entities; for large or read-only entities use `@Immutable` or `Session.refresh`. - `@DynamicUpdate` generates an UPDATE only for the changed columns (less traffic, avoids overwriting) — beware of less cacheable query plans. - Limit the **size of the Session/Persistence Context**: `clear()`/`detach()` in long loops; measure with `em.getEntityManagerFactory().getPersistenceUnitUtil()` and statistics. --- ## 🗄️ 4. Cache (L1, L2, and Query Cache) | Cache | Scope | Recommended use | | :--- | :--- | :--- | | **First-level (Session)** | Transaction/Session | Identity and object caching; always on | | **Second-level (L2)** | SessionFactory (multi-session) | Read-mostly data, references; use TTL/versioning | | **Query cache** | Query result | Only with few results and stable tables (invalidation is costly) | - **Concurrency strategies** (from strictest to lightest): `READ_WRITE` → `NONSTRICT_READ_WRITE` → `READ_ONLY`. - `NONSTRICT_READ_WRITE`: a light asynchronous lock; fine for read-mostly; never under high concurrent write (it invalidates too much). - **Providers**: JCache (Ehcache 3, Infinispan, Caffeine bridge); size L2 regions to the working set (do not "cache everything"). - **Read-through in the app**: an explicit Cache-Aside pattern ([system-design-scalability](../../engineering/practices/system-design-scalability/SKILL.md)) often beats L2 when the domain suits it. --- ## 🔒 5. Locking, Concurrency, and Transactions - **Optimistic (version/numeric)**: handle `OptimisticLockException` with a retry (short transaction); ideal for medium to low contention. Increment the version manually in bulk actions. - **Pessimistic**: `PESSIMISTIC_WRITE` (SELECT FOR UPDATE) for job queues, critical counters, bid/reserve stock; keep lock time minimal. - **Lost update**: the biggest silent plague — a reader and a writer in separate transactions; mitigations: optimistic locking, `PESSIMISTIC_FORCE_INCREMENT`, or atomicity in SQL (`UPDATE ... SET x = x + 1`). - **Isolation**: READ_COMMITTED plus versioning solves 90%; SERIALIZABLE only with good justification (cost in locks and anomalies even in Postgres SSI). --- ## 📑 6. Pagination and Queries - **OFFSET degrades badly** (it scans and discards): for deep pagination use **keyset/seek** (`WHERE (a.id > :last) ORDER BY a.id LIMIT :n`) — constant cost. - Modern standard SQL: `OFFSET ? ROWS FETCH FIRST ? ROWS ONLY` (SQL:2008); dialects vary — let Hibernate map it. - **Projections**: `SELECT new com.x.Dto(...)` for reads (against the traffic of managed entities); `Tuple`/interface-based projections for flexibility. - **Criteria API** for dynamic filters; beware of generating non-cacheable plans (use the query plan cache with constant parameters). - Measurement per database: `EXPLAIN (ANALYZE, BUFFERS)` (Postgres), `set showplan` (SQL Server), autotrace (Oracle) — validate the plan before and after ([db-postgresql](../db-postgresql/SKILL.md)). --- ## 🧭 7. Persistence Optimization Protocol 1. **Measure first**: `hibernate.generate_statistics=true` in dev; APM in prod; identify N+1, repeated queries, long sessions. 2. **Fix the fetch** (JOIN FETCH/EntityGraph) before touching the cache. 3. **Enable batching** and verify the wire (driver logs) — a batch that never reaches the database is pure overhead. 4. **Cache with policy**: L2 for read-mostly with TTL/versions; query cache rarely. 5. **Locking per case**: optimistic by default; pessimistic only for micro-intervals. 6. **Keyset pagination**; OFFSET only for small initial pages. 7. **Load tests** with realistic data (cardinality and skew) and verification of plans after index changes or migration. 8. **Django-like providers**: keep the driver and dialect up to date (optimizations arrive with each Hibernate/JDBC driver version). --- ## 🔗 Integration with Other Skills - [lang-java](../../languages/lang-java/SKILL.md): JPA fundamentals under concurrency and the JVM. - [db-postgresql](../db-postgresql/SKILL.md), [db-mariadb](../db-mariadb/SKILL.md), [db-sqlite](../db-sqlite/SKILL.md): tuning the target database (EXPLAIN, indexes, buffer). - [dba-database-administrator](../../roles/dba-database-administrator/SKILL.md): modeling, indexes, and reference queries. - [backend-developer](../../roles/backend-developer/SKILL.md): integration into Java services/APIs with short transactions. - [latency-engineering](../../engineering/practices/latency-engineering/SKILL.md): connection-pool round-trips and N+1 as p99 villains.
Auf GitHub ansehen