java-topology/whitepaper/outreach/hibernate-orm-0001.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.9 KiB
Raw Blame History

Hibernate ORM — CWE-407 Disclosure Brief (hibernate-orm-0001)

2026-04-13 · Patch available — awaiting upstream merge

Finding

One O(n²) defect in Hibernate ORM's foreign key second pass ordering. The buildRecursiveOrderedFkSecondPasses() method in InFlightMetadataCollectorImpl calls List.contains() on an ArrayList inside a recursive walk, producing O(N²) total cost for N foreign key constraints.

The Defect

hibernate-orm-0001 (PATCHED — HIGH): hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java:1835

// In buildRecursiveOrderedFkSecondPasses — recursive FK dependency walk:
if (!orderedFkSecondPasses.contains(fkSecondPass)) {  // O(N) ArrayList scan
    orderedFkSecondPasses.add(0, fkSecondPass);        // O(N) shift
}

orderedFkSecondPasses is an ArrayList. The contains() check is O(N) per call, and the add(0, ...) insert-at-head also shifts all existing elements. With N foreign keys, the recursive walk visits each FK at least once, giving O(N²) from contains alone.

Complexity Proof

At N=500 foreign keys:

  • Defective: 500 × 250 (avg) = ~125,000 comparisons for contains() alone
  • Fixed: 500 × O(1) HashSet lookups = 500 operations
  • ~250× op reduction. The add(0, ...) shift cost remains but contains() dominates.

Impact

Hibernate ORM is the most widely used JPA implementation, powering millions of Java applications. Schema bootstrap and metadata collection fire on every application startup. Enterprise schemas with hundreds of tables and foreign key constraints hit this path during SessionFactory creation. Slow startup cascades through CI/CD pipelines, test suites, and production deployments.

The Fix

Add a companion HashSet<FkSecondPass> for O(1) membership testing:

// Before
if (!orderedFkSecondPasses.contains(fkSecondPass)) {
    orderedFkSecondPasses.add(0, fkSecondPass);
}

// After — O(1) HashSet membership test
if (!orderedFkSecondPassSet.contains(fkSecondPass)) {
    orderedFkSecondPassSet.add(fkSecondPass);
    orderedFkSecondPasses.add(0, fkSecondPass);
}

Patch

Fix available: defects/hibernate-orm-0001/patch/hibernate-orm-0001-fk-secondpass-list-contains.patch

Single-file patch in InFlightMetadataCollectorImpl.java. Adds Set<FkSecondPass> parameter threaded through the recursive call chain. ~250× speedup at 500 foreign keys.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (hibernate/hibernate-orm).
  2. Assess severity — fires on every SessionFactory creation, scales quadratically with FK count.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the Hibernate team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.