Application Integration & Schema Evolution

ORM Impedance Mismatch

An ORM coordinates objects, identity, relationships, and changes over relational data, but object graphs and relations have different semantics. Use the abstraction deliberately, keep database constraints authoritative, and inspect the SQL and transaction behavior it emits.
  • Object identity and relational keys differ.
  • Associations are queries and constraints.
  • Inheritance has no single relational mapping.
  • Fetching is part of the API contract.
  • Change tracking emits concurrency behavior.
  • Abstractions leak at semantic boundaries.
Mismatch ledger
ConcernObject viewRelational/database realityControl
Identityreference / equalsprimary/candidate keystable key policy + identity map
Associationfield/collectionFK or join relationconstraints + explicit ownership
Inheritancesubtype polymorphismone/many tableschoose per query/constraint tradeoff
Fetchingnavigationround trips and row setsprojection/fetch plan + budgets
Change trackingmutated fieldsordered DML under concurrencyversion predicate + flush tests
Query leakrepository methodSQL types/plans/isolationinspect SQL and real-engine behavior
Define optimistic concurrency explicitly
ALTER TABLE orders ADD COLUMN row_version BIGINT NOT NULL DEFAULT 0;

UPDATE orders
SET status = :new_status, row_version = row_version + 1
WHERE order_id = :order_id
  AND row_version = :expected_version;
-- Exactly one affected row means the expected version won.
-- Zero means missing row or concurrent change; classify by the application contract.
One aggregate boundary
Order
  identity: order_id
  invariant: allowed status transition
  children: OrderItem identified by (order_id, line_no)
  concurrency token: row_version

Customer and Product are references by key, not automatically cascaded children.
Deletion, orphan removal, and loading are explicit use-case decisions.