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

Inheritance Mapping Strategies

ASecurity

Mapping a subtype hierarchy onto tables — single table, class table (joined), concrete table per class — and deciding whether the hierarchy should exist at all. Use when an @Inheritance strategy is being chosen, when a single-table mapping is forcing every subtype's columns to be nullable, when a joined mapping's polymorphic query joins six tables to render a list, when adding a subtype requires a migration, when a discriminator column has drifted from the class names, when polymorphic querie...

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

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill inheritance-mapping-strategies --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Inheritance Mapping Strategies?

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

Security grade badge for Inheritance Mapping Strategies
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-inheritance-mapping-strategies/badge)](https://www.skillsdirectory.com/skills/robsonkades-inheritance-mapping-strategies)

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

Download Zip
Files
SKILL.md
---
name: inheritance-mapping-strategies
description: >
  Mapping a subtype hierarchy onto tables — single table, class table (joined), concrete
  table per class — and deciding whether the hierarchy should exist at all. Use when an
  @Inheritance strategy is being chosen, when a single-table mapping is forcing every
  subtype's columns to be nullable, when a joined mapping's polymorphic query joins six
  tables to render a list, when adding a subtype requires a migration, when a discriminator
  column has drifted from the class names, when polymorphic queries are slow or return the
  wrong rows, when a hierarchy exists only to share three fields, or when composition would
  serve better than subtyping. Does not cover associations, identity and value mapping
  (orm-structural-mapping), where the mapping instructions live (metadata-mapping), the
  runtime fetch behaviour (orm-behavioral-patterns), or the domain question of whether
  subtypes model the business correctly (domain-logic-organization).
---

# Inheritance Mapping Strategies

## Purpose

Choose a subtype mapping with its query cost, its constraint capability and its evolution
cost all on the table. A Java subtype hierarchy does not determine one portable relational
representation: each strategy trades query shape against constraints and schema evolution.
Revisiting a populated mapping can require a migration even when the Java change is small.

Challenge hierarchies introduced only to share fields, but do not infer that a data-oriented
subtype is invalid: substitutability and distinct invariants matter as well as methods.

Inspect Java release/toolchain, persistence API (`javax` versus `jakarta`), provider/version,
dialect, generated SQL and managed migrations first. Guidance is checked against Jakarta
Persistence 3.2; TABLE_PER_CLASS support is optional there. Examples are partial sketches,
not complete entities. Java sealed types require 17, pattern-switch requires 21 without
preview; neither requires upgrading the target project.

## The three strategies

```text
Single table          one table, all subtypes, a discriminator column.
(SINGLE_TABLE)        Subtype-specific columns are commonly nullable;
                      discriminator-aware CHECK constraints can enforce groups.

Class table           one table per class in the hierarchy, joined by the
(JOINED)              shared primary key. Subtype entity loads generally join
                      through mapped levels; projections may not.

Concrete table        one table per concrete subtype, each with every
(TABLE_PER_CLASS)     column. No shared table, so polymorphic queries are
                      typically UNIONs or separate queries. An ordinary
                      FK cannot target the hierarchy without a base table.
```

## Workflow

Reuse the consumer queries, existing schema/constraints, public subtype contracts and change
goal before choosing annotations. Keep a mapping that already satisfies them. Ask only about
unresolved query, integrity or rollout requirements that could change the recommendation;
continue inspecting SQL and mappings while those answers are pending.

1. **Check the hierarchy's contract.** Inspect substitutability, identity and invariants as
   well as behaviour. Field-only differences invite comparison with composition but do not
   alone disprove a subtype or justify breaking existing consumers.
2. **Count the shape.** How many subtypes, how many columns each, how many are
   subtype-specific? Measure populated row width, indexes, constraints and query plans; column count alone
   does not determine cost.
3. **Establish the query mix.** Include selected fields, root versus subtype queries, write
   paths and incoming references. Compare a projection or index within the existing mapping
   with changing storage; polymorphic entity reads often favour single table, while joined
   can simplify subtype-local constraints. Check the actual provider SQL and database plan.
4. **Establish whether the database must enforce the subtype's required fields.** If yes,
   single table is out unless you are prepared to write check constraints.
5. **Establish the evolution rate.** A hierarchy that gains a subtype every quarter pays a
   migration per subtype under joined and concrete table, and may require columns, discriminator checks and indexes under single table.
6. **Decide or retain the mapping, and pin discriminator values** where used, so a class
   rename need not migrate data. Verify the relevant reads/writes/constraints and rollout
   contract; stop when the requirement is met. Record what missing evidence or workload
   change would warrant revisiting a conditional recommendation.

## Decision rules

```text
Subtypes only share fields and have no distinct substitution/invariant contract
        → compare composition or mapped-superclass reuse. An enum with embedded
          groups may fit; JSON requires explicit validation/query/index trade-offs.

Few subtypes, few subtype-specific columns, polymorphic queries common,
performance matters
        → SINGLE_TABLE often minimizes joins for polymorphic reads. Confirm
          row width, indexes, predicates and workload before claiming speed.
          Pay with nullable columns and explicit conditional-constraint design.

Many subtype-specific columns, or the database must enforce them, or
subtypes are large and distinct
        → compare JOINED's subtype-local constraints with SINGLE_TABLE checks
          and the actual workload. Joined FKs alone do not prove sibling
          exclusivity or base-row completeness; verify required invariants.
          Base projections need not load every subtype.

Subtypes are genuinely unrelated in storage terms, never queried
polymorphically, and no other table needs a foreign key to the base
        → TABLE_PER_CLASS. Rarely the right answer; an ordinary FK needs a single referenced table;
          hierarchy-wide queries usually require UNIONs or separate queries.

The hierarchy is deep (3+ levels)
        → inspect mapped levels and actual fields/SQL before flattening.
          Depth can add joins; it does not itself add SINGLE_TABLE columns.

Variation is per-tenant or per-configuration, and new variants must ship
without a deploy
        → compare data-driven policy/composition using supported operations.
          Choose relational fields/rows versus JSON or serialized data from
          validation, query/index, update and compatibility needs; configuration
          alone does not implement new behaviour (orm-structural-mapping).
```

## Rules

- **Single table's real cost includes constraint complexity, not just disk.** Columns may remain
  nullable at the column level while discriminator-aware `CHECK` constraints enforce “a
  `CardPayment` must have `card_last4`.” Verify ORM-generated DDL and bulk/import paths, or
  accept that only application code enforces it — and that bulk imports bypass it.
- **Joined entity materialization often joins mapped levels/subtypes**, while base-only
  projections can avoid them; writes span the tables holding the entity state. It is usually acceptable; it becomes painful on a list
  screen that reads the whole hierarchy at volume, and that is a measurable question, not a
  matter of taste (`architecture-and-performance`).
- Concrete table per class has no single base table for an ordinary polymorphic foreign key.
  Alternatives such as separate subtype FKs, a registry/base identity table or application-level
  integrity add complexity; price them before excluding the strategy.
- **Pin stored discriminator values** where used (`@DiscriminatorValue("CARD")`). For a
  STRING discriminator the default is the entity name; an unpinned entity name follows the
  class name. Preserve existing values during renames, including explicit entity/table names.
- Query costs depend on selected attributes, predicates, fetches and provider SQL. A root
  SINGLE_TABLE query need not filter the discriminator at all; fewer joins do not guarantee
  a cheap plan. Inspect plans and representative workload before comparing strategies.
- For mapping reuse without a subtype contract, compare `@MappedSuperclass` (shared
  mapping, no entity-root polymorphism or base table) with composition. Audit fields and
  shared identifiers can fit it; do not remove a legitimate persistent hierarchy merely
  because its fields look similar.
- Adding a subtype may need new columns/checks/indexes (single table), a new mapped table
  and FK (joined), or a concrete table. Locking and scan/rewrite costs depend on the exact
  database/version and DDL; additive does not mean online. Changing
  strategy later usually requires a substantial data migration. It is expensive, not literally
  one-way; use expand/contract, reconciliation and rollback/forward-fix analysis
  (`architecture-decision-making`).
- Choose indexes from predicates and selectivity. Partial/filtered indexes can help sparse
  subtype data where supported and where the query implies their predicate; inspect the
  generated, possibly parameterized SQL and plan.
- If `PremiumCustomer` and `StandardCustomer` differ only in a configurable discount rate
  and have no distinct substitution/invariant contract, one type with a policy may be enough.
  Preserve actual business and consumer distinctions; hand off unresolved domain meaning to
  `domain-logic-organization`.

For a recommendation or no-change result, report query/DDL evidence, the integrity and
migration trade-offs, actual checks and any targeted validation still needed. Without plans
or workload data, keep performance conclusions conditional; a proposed migration is not
completed implementation.

## References

- [Strategy comparison](references/strategy-comparison.md) — the three strategies with
  their DDL, their generated SQL for the queries that matter, query-cost hypotheses,
  constraint enforcement including conditional check constraints, indexing under each, and
  the alternatives to inheritance with the shape that replaces it. Read when choosing a
  strategy or justifying an existing one.
- [Schema evolution](references/schema-evolution.md) — what adding, removing, splitting or
  moving a subtype costs under each strategy; discriminator value management and renames;
  migrating between strategies with an expand/contract sequence; and the read-model options
  when the write-side mapping is right but reads are expensive. Read before changing a
  hierarchy that has data in it.

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 →