PERSISTENCE FEATURE
Shared Table Extension
This is the ORM painkiller: later modules add columns to an existing table without reopening the original resource class.
Feature Guide
A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.
What this does
Two modules can point at the same table and contribute their own columns without one module editing the other module's resource class.
How it works
SchemaCollector groups discovered ORM resources by table name. When another resource maps to the same table, it adds only missing columns and leaves already-defined columns alone.
Why it matters
This removes one of the most painful ownership traps in modular systems: the first module does not permanently own the whole table forever. Later modules stay additive instead of invasive.
Key concepts
- Shared table extension
- Multiple ORM resources map to one physical table and extend its schema collaboratively.
- SchemaCollector
- Collects table definitions from resource attributes and merges columns by table name.
- Module isolation
- A later module can add persistence fields without reopening the source code of the original module.
ORM Kill Feature
One table. Two modules. Zero cross-module edits.
In most stacks, the second module has to reopen the first module's model just to add a few extra columns. Semitexa keeps that additive: both resources point at the same table, and schema collection merges the result.
Why teams hate the usual approach
- One module usually becomes the permanent owner of a table, even when another bounded context needs to extend it later.
- The follow-up module often has to edit the original model class, creating ownership bleed and merge pressure between teams.
- That coupling turns harmless extra columns into a cross-module coordination problem instead of an additive change.
Owns the initial product shape that the storefront and admin tools already depend on.
Arrives later and adds campaign-only fields without reopening the catalog module.
| Merged column | Owned by | Why it stays safe |
|---|---|---|
id |
Catalog | Base primary key stays untouched. |
tenant_id |
Catalog | Tenant scoping still applies to the shared table. |
name |
Catalog | Core commerce data remains where it started. |
description |
Catalog | Existing product content is unchanged. |
price |
Catalog | Base module continues to own pricing semantics. |
status |
Catalog | Lifecycle state stays with the core domain. |
badge_label |
Merchandising | Added later for campaign UX. |
merch_priority |
Merchandising | Supports merchandising sort logic. |
campaign_code |
Merchandising | Connects rows to external campaign flows. |
Verified against Semitexa Ultimate 2026.09.19.1020
Shared Table Extension
Two ResourceModel classes in different modules can target the same physical table with #[FromTable]. The SchemaCollector merges their column sets into one schema plan.
How it works
The base module defines the core resource with #[FromTable('products')] and declares its columns. A later module creates its own resource, also pointing at #[FromTable('products')], and declares only its additional columns. At sync time, SchemaCollector groups all discovered resources by table name and only adds missing columns — it never redefines existing ones. Neither module needs to open or modify the other's class.
Why this matters
Without shared table extension, a later module either has to edit the original resource class (creating cross-module ownership bleed) or maintain a separate table (creating join complexity). The additive model keeps module boundaries clean and schema evolution safe.
How it works
SchemaCollector groups discovered ORM resources by table name. When another resource maps to the same table, it adds only missing columns and leaves already-defined columns alone.
Why it matters
This removes one of the most painful ownership traps in modular systems: the first module does not permanently own the whole table forever. Later modules stay additive instead of invasive.
Key concepts
- Shared table extension
- Multiple ORM resources map to one physical table and extend its schema collaboratively.
- SchemaCollector
- Collects table definitions from resource attributes and merges columns by table name.
- Module isolation
- A later module can add persistence fields without reopening the source code of the original module.