Skip to content

Phase 5: CritterMapper implementation#4224

Open
evanchooly wants to merge 5 commits intomasterfrom
critter-phase5
Open

Phase 5: CritterMapper implementation#4224
evanchooly wants to merge 5 commits intomasterfrom
critter-phase5

Conversation

@evanchooly
Copy link
Copy Markdown
Member

Summary

  • Implements CritterMapper extends AbstractMapper with three-tier entity model discovery
  • Tier 1: loads pre-generated model from classpath by naming convention (critter-maven AOT)
  • Tier 2: generates model at runtime via CritterGizmoGenerator (Gizmo + VarHandle)
  • Tier 3: falls back to reflection-based EntityModel
  • copy() shares immutable CritterEntityModel references; clones reflective fallback models
  • Per-type fallback logging via ConcurrentHashMap.newKeySet() (logs once, not on every access)
  • synchronized mapEntity prevents concurrent duplicate-discriminator race condition

Closes #4187

Test plan

  • TestCritterMapper — 8 tests: runtime generation, collection name, caching, copy semantics, concurrent access, null/non-entity inputs
  • Full morphia-core suite — 1,231 tests, zero failures

🤖 Generated with Claude Code

evanchooly and others added 5 commits March 31, 2026 08:57
Tests cover runtime model generation, caching, copy semantics, null/non-entity
handling, and concurrent mapping. Tests intentionally fail to compile until
CritterMapper is implemented.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- testCopyHasIndependentDiscriminatorLookup: assert discriminator
  lookup instances are not same (not just mapper instances)
- testConcurrentMappingProducesSingleModel: collect all futures first,
  shut down pool before assertions
- Replace fully-qualified org.testng.Assert.assertNull calls with
  static import assertNull
- Add explicit no-arg constructor to CritterMapperTestEntity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds CritterMapper as a hybrid mapper that discovers entity models via:
1. Pre-generated models from the classpath (critter-maven AOT output)
2. Runtime Gizmo+VarHandle generation via CritterGizmoGenerator
3. Reflection-based fallback (standard EntityModel)

The copy constructor shares immutable CritterEntityModel references across
copies while creating independent DiscriminatorLookup instances. mapEntity
is synchronized to prevent concurrent registration of the same type.

All 8 TestCritterMapper tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erMapper

Add a comment on the copy constructor explaining why super(other) cannot be
used (it would call new EntityModel() for CritterEntityModel instances) and
the resulting known discrepancy that custom converters registered post-
construction are not shared with copies. Add a comment on mapEntity explaining
why the method is synchronized (race condition in DiscriminatorLookup).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Make copy constructor public with @MorphiaInternal annotation
- Add @hidden and @morphia.internal Javadoc tags to both constructors
- Change LOG.error to LOG.warn for graceful fallback paths in
  tryLoadPregenerated and tryRuntimeGeneration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[0%] Phase 5: CritterMapper implementation

1 participant