Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Orm Behavioral Patterns

ASecurity

The three runtime behaviours that make object-relational mapping work and produce its most confusing failures: Unit of Work, Identity Map and Lazy Load. Use when an entity was modified but never saved and the change appeared anyway, when a change was expected to persist and did not, when LazyInitializationException appears during serialisation or in a job, when the query count scales with rows displayed, when a persistence context grows until flush becomes slow, when a bulk update is invisibl...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmentjavasqlspringdatabaseperformance

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill orm-behavioral-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Orm Behavioral Patterns?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Orm Behavioral Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-orm-behavioral-patterns/badge)](https://www.skillsdirectory.com/skills/robsonkades-orm-behavioral-patterns)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: orm-behavioral-patterns
description: >
  The three runtime behaviours that make object-relational mapping work and produce its most
  confusing failures: Unit of Work, Identity Map and Lazy Load. Use when an entity was
  modified but never saved and the change appeared anyway, when a change was expected to
  persist and did not, when LazyInitializationException appears during serialisation or in a
  job, when the query count scales with rows displayed, when a persistence context grows
  until flush becomes slow, when a bulk update is invisible to loaded entities, or when Open
  Session In View is being turned on to make an error disappear. Does not cover the mapping
  itself (orm-structural-mapping), which data-access pattern to use (data-source-patterns),
  transaction boundaries (enterprise-transactions), or whether to cache the read at all
  (caching-strategies).
---

# ORM Behavioral Patterns

## Purpose

Make the ORM's runtime behaviour visible and predictable. Unit of Work, Identity Map and
Lazy Load change what code does. These patterns explain common surprises about tracked
changes, repeated identities and deferred reads; establish the actual mechanism before
attributing a persistence failure to one of them.

## The three patterns

```text
Unit of Work    tracks managed state and pending persistence operations,
                synchronizing at flush (possibly before commit).
                Dirty changes need no save() on managed entities;
                SQL ordering is distinct from optional JDBC batching.

Identity Map    maintains one managed object instance per database identity
                in a persistence context. Consequence: repeated identity lookup
                may avoid SQL, while queries can still execute and resolve to the SAME
                managed instance, so a modification through one reference is
                visible through every other.

Lazy Load       defers data access using proxies, collections or enhancement on
                first access. Consequence: a query happens where the code
                shows a getter, possibly outside a transaction, possibly
                once per row of a loop.
```

JPA providers realize these patterns through persistence-context tracking, managed identity
and their lazy-loading mechanisms. The pattern explains the responsibility; the provider,
mapping and runtime settings determine how it is implemented.

## Workflow

Use the steps relevant to the state, lifecycle or query question. Reuse adequate evidence;
a narrow explanation or supported no-change review does not require new logging, a full
fetch comparison or a persistence-context redesign.

1. **Establish the runtime and unit of work.** Inspect JPA/Hibernate, Spring and Java versions,
   mappings, flush mode and context ownership. A transaction-scoped persistence context
   commonly ends at commit; extended/application-managed contexts or OSIV can outlive it.
2. **Know which objects are managed.** Managed (tracked, changes flushed), detached (not
   tracked; changes remain in memory but are not automatically synchronized), transient
   (not yet managed/persisted), removed. Check actual state and transaction outcome.
3. **Predict the applicable synchronization points.** Explicit flush, commit, and queries
   under the target provider's flush mode. Hibernate AUTO commonly flushes before an
   overlapping entity query; this is not a promise that every query issues writes.
4. **Budget the queries.** Lazy traversal can issue queries depending on loaded state,
   cache and batch/fetch configuration
   (`architecture-and-performance`). Choose the fetch plan for actual use-case requirements;
   detailed query-count and batching tuning belongs to `orm-fetch-and-batching-performance`.
5. **Bound the context's size.** Long-running units of work retain entities and snapshots; flush
   cost generally grows with managed state and can become worse through cascades/collections. Measure
   rather than assuming quadratic complexity.
6. **Confirm the disputed behavior with relevant evidence.** Statement logs show SQL execution;
   state inspection, transaction outcome and fresh-context reads answer different questions.
   Add only the missing observation needed to distinguish plausible causes.

## Decision rules

```text
An entity remains managed, writable and dirty in a context joined to a committing transaction
        → expect synchronization at flush/commit. Calling save() is redundant, and
          NOT calling it does not prevent the write. If you do not want
          the write, do not modify a managed entity.

An entity's persistence context ended or it was detached, then modified
        → changes are not automatically synchronized. Re-read or merge deliberately;
          merge returns the managed target and may issue a SELECT.

A collection is traversed once per row of a result set
        → inspect for N+1. Consider a join fetch, an entity graph, batch fetching, or
          a projection. Eager mapping alone does not establish a bounded query plan;
          inspect its effect on the other entity-loading paths.

An association is needed by only some callers
        → prefer a conservative mapping and fetch explicitly where needed. Retain
          an adequate eager requirement when its loading/cost contract is intentional.

LazyInitializationException on access to uninitialized state
        → inspect that proxy/collection's session and loaded state: detached,
          closed or disconnected is not the same as merely "no transaction".
          Fetch what the caller needs in its owning context, reload in the proper
          unit of work, or map a loaded result there. Turning on Open Session In
          View may hide it while allowing unplanned queries during serialisation.

A batch's retained context or flush work exceeds its budget
        → measure retained state and flush cost; flush/clear bounded chunks
          or assess stateless semantics. Context size is not the only transaction cost.

A bulk UPDATE/DELETE via JPQL or SQL ran in this transaction
        → affected loaded entities may be stale; inspect explicit version handling.
          Flush required pending changes before bulk work, then clear/refresh deliberately, and mind
          optimistic locking (offline-concurrency-control).

The same row must be represented by two independent managed instances
        → not within the same persistence context. Independent projections or
          detached snapshots can coexist; use a separate context when managed identity
          really must be independent, accounting for consistency and write ownership.
```

## Rules

- **Writable managed changes can persist without save().** A managed entity
  modified for a temporary calculation can persist on successful flush/commit. This is a
  cause of unexplained updates in a log, and the fix is not to detach defensively but to
  stop mutating managed objects for non-persistent purposes.
- JPA dirty checking does not require `save()` for a managed entity. Spring Data's `save()` still
  invokes persist/merge according to its new-entity detection; `merge` copies state into a managed
  instance and may require a SELECT depending on identity/version/context. Use the returned instance
  and verify SQL for the provider/version instead of relying on a universal call shape.
- Hibernate 6.6 queues entity actions in its own order; JPA does not promise source-order SQL.
  A delete-then-insert of a conflicting unique key can therefore insert first and fail.
  Consider updating the existing row, or flush the deletion before the insertion where
  that ordering satisfies the transaction and constraint contract.
- **A query can flush.** With applicable AUTO flush behavior, Hibernate flushes before a query that might read tables
  with pending changes, so a write/query loop can flush each iteration. Check overlap,
  effective mode and actual work before attributing batch cost to it.
- The identity map belongs to the persistence context. Separate contexts have independent
  managed instances; an extended context can span transactions without becoming a second-level
  cache. A second-level cache has separate invalidation and staleness concerns
  (`caching-strategies`).
- Choose entity equality for the required identity contract. Default reference equality is
  valid when independent instances should differ; it does not equate separate instances of
  the same persistent row across contexts. If value/persistent identity is required, design
  `equals`/`hashCode` together and keep hashes stable while objects are in hashed collections;
  naively using a generated identifier can change the hash after persist.
- Lazy loading is a performance/availability decision paid at access time. Prefer explicit use-case
  fetch plans and conservative default graphs; note that JPA defaults to eager for to-one mappings
  and `LAZY` can be a provider hint depending on mapping/provider capabilities.
- `LazyInitializationException` identifies uninitialized state without a usable initialization
  context; inspect the actual session association and lifecycle. Open
  Session In View extends persistence-context lifetime through rendering; it can trigger unplanned
  queries and connection churn outside the service transaction. It does not necessarily hold one
  database transaction or connection for the entire request—connection handling/provider settings
  matter
  (`architecture-and-performance`).
- JPQL bulk statements bypass managed entity change tracking. They do not update loaded state
  or run per-entity lifecycle callbacks; ordinary bulk updates do not automatically check or
  increment versions. Explicit assignments, provider extensions or database triggers can alter
  version behavior, so inspect the actual operation.
  They remain useful for set-shaped work; reconcile pending changes and stale managed state,
  and handle optimistic locking explicitly. A fresh context or selective refresh can avoid
  clearing unrelated managed work.
- Do not give independently owned cache/session consumers a live mutable managed graph.
  For a response or detached snapshot, define required loaded state, mutation ownership,
  serialization exposure/cycles and compatibility. DTOs/projections often make that contract
  explicit; an already adequate bounded representation needs no automatic conversion
  (`session-state-strategies`, `remote-facade-and-dto`).

## References

Return the observed state/SQL behavior, its likely mechanism and confirming evidence, the
smallest correction or supported no-change verdict, and validation gaps. SQL shows execution,
not proof of commit; verify a disputed persistence result from a fresh context after transaction completion. Examples are partial
JPA/Hibernate/Spring snippets; adapt to resolved versions, without upgrading to use this skill.

- [Unit of Work and Identity Map](references/unit-of-work-and-identity-map.md) — entity
  states and the transitions that lose data, flush timing and ordering, dirty checking cost
  and context growth, merge versus re-read, batch chunking, and how bulk operations
  interact with both patterns. Read when a write did not happen, happened unexpectedly, or
  a batch is slow.
- [Lazy Load](references/lazy-load.md) — proxy mechanics and what triggers a fetch, the
  four fetch strategies with their query counts and their failure shapes, pagination with
  fetch joins, initialization-context failures and context-dependent remedies, and lazy
  loading across a serialisation or a network boundary. Read when diagnosing N+1 or a lazy
  initialisation failure.

Attribution

robsonkadesrobsonkades
View sourceMore from robsonkades →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →