Phase 1: Extract Mapper interface and add MapperType config option#4193
Merged
evanchooly merged 8 commits intomasterfrom Feb 28, 2026
Merged
Phase 1: Extract Mapper interface and add MapperType config option#4193evanchooly merged 8 commits intomasterfrom
evanchooly merged 8 commits intomasterfrom
Conversation
- Convert Mapper.java from class to interface (@MorphiaInternal) - Extract AbstractMapper with shared entity registration/lookup logic - Create ReflectiveMapper extends AbstractMapper (current implementation) - Add MapperType enum (LEGACY, CRITTER) to dev.morphia.mapping - Add mapper() method to MorphiaConfig with default LEGACY - Update ManualMorphiaConfig to copy/store mapper field - Update MorphiaDatastore to use createMapper() factory (CRITTER branch throws UnsupportedOperationException until Phase 4) - Add invalid.mapper.config message to sofia.properties - Fix TestMapper to use mapper.copy() instead of new Mapper(mapper) All existing tests pass (1166 run, 1 skipped). Closes #4184 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generators.kt and TestEntityModelGenerator.kt were calling new Mapper(config) directly, which no longer compiles now that Mapper is an interface. Updated both to use ReflectiveMapper(config) instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR lays the groundwork for the planned CritterMapper integration by making Mapper an internal interface, moving shared mapping/registration logic into a new AbstractMapper, and routing mapper selection through configuration (defaulting to the legacy reflection-based implementation).
Changes:
- Refactors
Mapperfrom a concrete class into a@MorphiaInternalinterface and extracts shared logic intoAbstractMapper. - Introduces
ReflectiveMapperas the legacy reflection-based implementation and updatesMorphiaDatastoreto create mappers via a factory method. - Adds
MapperTypeand a newMorphiaConfig.mapper()configuration option (plus docs + Sofia message updates).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/modules/ROOT/examples/complete-morphia-config.properties | Documents the new morphia.mapper config option and possible values. |
| core/src/test/java/dev/morphia/test/mapping/TestMapper.java | Updates mapper cloning test to use Mapper.copy() now that Mapper is an interface. |
| core/src/main/resources/sofia.properties | Adds a message key intended for invalid mapper configuration handling. |
| core/src/main/java/dev/morphia/mapping/Mapper.java | Converts Mapper to an internal interface, defining the mapper contract. |
| core/src/main/java/dev/morphia/mapping/AbstractMapper.java | New shared base class holding most of the previous Mapper implementation logic. |
| core/src/main/java/dev/morphia/mapping/ReflectiveMapper.java | New legacy reflection-based mapper implementation extending AbstractMapper. |
| core/src/main/java/dev/morphia/MorphiaDatastore.java | Switches datastore to create the mapper via createMapper(config) and wires in mapper() selection. |
| core/src/main/java/dev/morphia/mapping/MapperType.java | Adds the MapperType enum (LEGACY, CRITTER) for config-driven selection. |
| core/src/main/java/dev/morphia/config/MorphiaConfig.java | Adds mapper() with default legacy and a fluent updater mapper(MapperType). |
| core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java | Stores and defaults the new mapper config field to MapperType.LEGACY. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9 tasks
Parent issue percentage is now (completed_tasks_across_all_phases / 53) * 100 instead of (completed_phases / 7) * 100. Clarifies that the parent title should be updated after every individual task completion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- tryGetEntityModel: map actual (unwrapped) type not proxy type - isMappable: add null guard before isAssignableFrom to avoid NPE - createMapper: replace hard-coded string with Sofia.mapperNotYetAvailable() and throw MappingException instead of UnsupportedOperationException Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- .github/scripts/update-critter-progress.sh: reusable script that fetches checkbox state from all 7 phase issues, computes phase % and parent % (total_done/53), updates issue titles, closes completed phases, and checks their boxes in #4179 - .github/workflows/update-critter-progress.yml: triggers on any merged PR or any edit to issues #4179/#4184-#4190 (e.g. checkbox ticked) - .claude/skills/update-progress/SKILL.md: Claude-invocable skill for manual progress updates with formula reference and phase table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Mapper.javafrom a concrete class to a@MorphiaInternalinterfaceAbstractMapperwith all shared entity registration, lookup, and lifecycle logicReflectiveMapper extends AbstractMapper— the current reflection-based implementationMapperTypeenum (LEGACY,CRITTER) todev.morphia.mappingmapper()method toMorphiaConfig(default:LEGACY) andManualMorphiaConfigMorphiaDatastoreto use acreateMapper()factory method (wired for Phase 4/5)invalid.mapper.configmessage tosofia.propertiesThis is the foundation for the CritterMapper integration. All 1,166 existing tests pass unchanged since everything continues to use
ReflectiveMappervia theLEGACYdefault.Closes #4184
Part of #4179
Test plan
./mvnw install -pl :morphia-core -am -DskipTests -Ddeploy.skip=true— clean compile./mvnw test -pl :morphia-core -Ddeploy.skip=true— 1166 tests pass, 1 skipped (pre-existing)🤖 Generated with Claude Code