Extract hydration from Relational into AbstractMapper - #14
Conversation
alganet
commented
Mar 18, 2026
- Add resolveEntityName() to Collection with polymorphic override in Typed that reads the discriminator column via EntityFactory
- Move Filtered persist delegation to AbstractMapper::persist(), so any backend routes filtered collections to their parent automatically
- Move postHydrate()/tryHydration() to AbstractMapper as protected methods for FK-to-object wiring using Style naming conventions
- Move buildEntitiesInstances() to AbstractMapper for collection-tree entity creation with Filtered skip and Composite duplication
- Rewrite InMemoryMapper to use shared postHydrate() instead of custom resolveRelations(), proving the abstraction works outside SQL
- InMemoryMapper now supports Typed collections via resolveEntityName()
- Remove unnecessary local variable aliases for $this->entityFactory
There was a problem hiding this comment.
Pull request overview
This PR refactors entity hydration and related-entity wiring into AbstractMapper, adds a per-row entity-name resolution hook on Collection (with a polymorphic override in Typed), and updates the in-memory test mapper to consume the shared hydration logic.
Changes:
- Add
Collection::resolveEntityName()and override it inCollections\Typedusing a discriminator column read viaEntityFactory. - Move hydration wiring logic into
AbstractMapper(postHydrate()/tryHydration()) and updateInMemoryMapperto use it. - Add
Filteredpersist delegation inAbstractMapper::persist()and introducebuildEntitiesInstances()as a shared helper.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| tests/InMemoryMapper.php | Refactors relation fetching to build an entity graph + call shared postHydrate(), and uses resolveEntityName() for Typed collections. |
| src/Collections/Typed.php | Implements discriminator-based entity resolution via resolveEntityName(). |
| src/Collections/Collection.php | Introduces the resolveEntityName() extension point on all collections. |
| src/AbstractMapper.php | Adds Filtered persist routing, shared hydration wiring helpers, and shared entity-instance building helper. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
- Add resolveEntityName() to Collection with polymorphic override in Typed that reads the discriminator column via EntityFactory - Move Filtered persist delegation to AbstractMapper::persist(), so any backend routes filtered collections to their parent automatically - Move postHydrate()/tryHydration() to AbstractMapper as protected methods for FK-to-object wiring using Style naming conventions - Move buildEntitiesInstances() to AbstractMapper for collection-tree entity creation with Filtered skip and Composite duplication - Rewrite InMemoryMapper to use shared postHydrate() instead of custom resolveRelations(), proving the abstraction works outside SQL - InMemoryMapper now supports Typed collections via resolveEntityName() - Remove unnecessary local variable aliases for $this->entityFactory
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #14 +/- ##
=============================================
- Coverage 100.00% 96.13% -3.87%
- Complexity 138 157 +19
=============================================
Files 13 13
Lines 349 388 +39
=============================================
+ Hits 349 373 +24
- Misses 0 15 +15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|