Entities through a maintained ORM.
Optional Doctrine integration with a fresh EntityManager and connection for each scope.
Install for production use
The development lock includes Doctrine ORM 3.7.0, DBAL 4.4.4 and Symfony Cache 8.1.6 for integration tests. They are development dependencies in the preview. If your application uses ORM in production, promote them to runtime requirements before building with --no-dev. Native lazy objects require PHP 8.4+.
composer require 'doctrine/orm:^3.5' 'symfony/cache:^8.0'Register once at bootstrap
use Icom\Orm\OrmFactory;
use Doctrine\ORM\EntityManagerInterface;
$orm = new OrmFactory(
['driver' => 'pdo_sqlite', 'path' => __DIR__.'/storage/entities.sqlite'],
[__DIR__.'/app/Entities']
);
$orm->register($app->container);
// Controllers and queue handlers can inject EntityManagerInterface.
// Entity classes use Doctrine mapping attributes; see tests/Fixtures/.Scope and persistence
Each scope opens a fresh EntityManager/connection. Cleanup rolls back active transactions, closes the manager and disconnects. Metadata is cached in a shared in-process ArrayAdapter; identities and managed entities are never shared between requests. Flush explicitly. Never keep an EntityManager or managed entity in a singleton, and never return a lazy entity from a scope after that scope has closed.
Tested surface and limits
SQLite integration tests persist related entities, load a lazy relationship, verify bound query input, roll back abandoned transactions and verify a new scope has a different manager. This is an integration with Doctrine, not a new ORM implementation. Use reviewed schema migrations for production; runtime SchemaTool schema creation is only a test technique. MySQL/PostgreSQL, connection-loss recovery, persistent metadata services and application-specific mappings require their own integration tests.