icom/ framework

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+.

example
composer require 'doctrine/orm:^3.5' 'symfony/cache:^8.0'

Register once at bootstrap

example
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.

Doctrine getting started ↗

Developer preview — benchmark claims require reproducible evidence.

Explore the architecture