Doctrine ORM: Die richtige Versionsstrategie für Ihre PHP-Projekte

Doctrine ORM: Die richtige Versionsstrategie für Ihre PHP-Projekte

Drei Viertel aller Doctrine-Projekte nutzen noch die veraltete Version 2.x, während das Support-Ende im Februar 2027 unaufhaltsam näher rückt. Erfahren Sie, warum blindes Updaten innerhalb der 2er-Reihe riskant ist und wie Sie den strategischen Wechsel auf ORM 3.x sicher vollziehen. Diese Entscheidungsmatrix hilft Agenturen dabei, den richtigen Zeitpunkt für die Migration zu finden und ihre Symfony-Projekte zukunftssicher aufzustellen.

Dennis Schwenker-Sanders 9 Min. Lesezeit

Doctrine ORM ist das Rückgrat der meisten Symfony-Projekte. Und genau dieses Rückgrat steckt gerade in einer Übergangsphase, die jede Agentur betrifft: ORM 2.x geht in den Restricted Maintenance Mode, ORM 3.x ist die stabile Gegenwart, und ORM 4.0 hat die Entwicklung aufgenommen. Die Adoptionsrate von ORM 3 liegt laut Packagist-Daten bei nur 25 bis 30% der ORM-2-Installationen. Drei Viertel aller Doctrine-Projekte laufen noch auf der alten Version.

Das wäre kein Problem, wenn ORM 2.x unbegrenzt gewartet würde. Aber seit März 2026 gilt die Restricted Maintenance Policy: In den 2.x-Branch fließen nur noch PHP-Versionskompatibilität, Security-Fixes und Forward-Kompatibilität mit ORM 3. Keine Bug-Fixes, keine Verbesserungen. Das End-of-Life ist für mindestens Februar 2027 geplant.

Für Agenturen, die mehrere Kundenprojekte auf Doctrine ORM betreiben, entsteht jetzt ein konkreter Handlungsbedarf: Welche Projekte migrieren Sie auf ORM 3? Welche bleiben auf 2.x, bis ORM 4.0 kommt? Und was bedeutet das für Shopware-Projekte, die ihre eigene Doctrine-Version mitbringen?

Die gute Nachricht: Die Doctrine-Maintainer haben die Migration bewusst erleichtert. Einige Deprecations aus dem initialen 3.0-Release wurden zurückgenommen (Partial Objects sind wieder erlaubt). Die Upgrade-Guides wurden verbessert. Und ORM 3.6.3 (erschienen am 2. April 2026) ist stabil genug für neue Projekte. Was fehlt, ist eine klare Entscheidungsmatrix: Wann lohnt sich die Migration, wann nicht, und worauf müssen Sie achten?

Aktueller Versionsstand: Was wo steht

ORM 2.20.10: Maintenance mit Einschränkungen

Am 2. April 2026 erschien ORM 2.20.10 als Maintenance-Release unter der Restricted Policy. Ein häufiger Fehler, den ich in Audits sehe: Teams aktualisieren blind auf das neueste 2.x-Release, ohne den Changelog zu prüfen. Bei 2.20.10 ist Vorsicht geboten: Doctrine selbst empfiehlt in bestimmten Fällen ORM 3.5.6 statt 2.20.10, weil Bug-Fixes aus 2.20.8 nicht vollständig in die spätere Version übernommen wurden.

Das klingt verwirrend und ist es auch. Die Hintergründe sind pragmatisch: Unter der Restricted Policy werden Bug-Fixes nur noch selektiv in den 2.x-Branch gemerged. Fixes, die eng mit ORM-3-Features verknüpft sind, werden nicht zurückportiert. Das führt zu einer Situation, in der die "neueste" 2.x-Version nicht automatisch die "beste" ist.

ORM 3.6.3: Die stabile Gegenwart

ORM 3.6.3, ebenfalls am 2. April 2026 erschienen, ist ein reines Bugfix-Release und stabil für Production. ORM 3 erfordert PHP 8.1+ und Symfony 6.4+. Seit ORM 3.4.0 werden Native Lazy Objects (PHP 8.4) und Property Hooks unterstützt, was die Performance und Developer Experience deutlich verbessert.

Aus meiner Projekterfahrung: ORM 3.x ist für Greenfield-Projekte die klare Empfehlung. Die API ist moderner, die Typisierung strenger, und die Performance-Optimierungen (besonders bei Hydration und Proxy-Generierung) sind spürbar. Wie ich im KW16-Artikel zu Doctrine ORM 4.0 beschrieben habe, setzt ORM 4.0 vollständig auf Native Lazy Objects. Wer jetzt auf ORM 3.x mit PHP 8.4 migriert, kann die neue Proxy-Architektur bereits optional nutzen und sich auf ORM 4.0 vorbereiten.

ORM 4.0: Am Horizont

ORM 4.0 ist in aktiver Entwicklung. Der GitHub-Milestone zeigt über 80% Fortschritt. PHP 8.4 wird das Minimum, Native Lazy Objects werden Pflicht. Ein Hackathon ist für Herbst 2026 geplant, Release möglicherweise Ende 2026 oder Anfang 2027. Für die Versionsstrategie bedeutet das: ORM 3.x ist die Brücke zwischen der Legacy-Welt (2.x) und der Zukunft (4.0).

Deep-Dive: Die Breaking Changes zwischen ORM 2 und 3

Welche Änderungen betreffen Ihre Projekte am meisten?

Was auf den ersten Blick einfach wirkt (Composer-Version ändern, Deprecations fixen, fertig), hat in Production Implikationen für die gesamte Datenbank-Schicht. Die wichtigsten Breaking Changes:

Entity Listener Syntax: ORM 3 erzwingt PHP-8-Attribute statt Annotations. Wer noch @ORM\Entity Annotations nutzt, muss auf #[ORM\Entity] Attribute umstellen. Das betrifft jede Entity-Klasse, jeden Repository-Aufruf, jede Mapping-Definition.

// ORM 2.x: Annotations (wird nicht mehr unterstützt in ORM 3)
/** @ORM\Entity(repositoryClass="App\Repository\ProductRepository") */
class Product
{
    /** @ORM\Id @ORM\Column(type="integer") */
    private int $id;
}

// ORM 3.x: PHP 8 Attributes
#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    private int $id;
}

Flush-Verhalten: In ORM 2.x konnten Sie einzelne Entities flushen ($em->flush($entity)). In ORM 3.x ist nur noch $em->flush() ohne Parameter erlaubt. Das erzwingt ein sauberes Unit-of-Work-Pattern, kann aber in Legacy-Code erhebliches Refactoring erfordern. In der GitHub-Diskussion zu Migration-Blockern war diese Änderung einer der meistgenannten Punkte.

Proxy-Generierung: ORM 3 generiert Proxies anders. Tools, die auf generierte Proxy-Dateien im Dateisystem angewiesen sind (Cache-Warming, Deployment-Scripts, Custom-Serializer), müssen angepasst werden. Ab ORM 3.4 mit PHP 8.4 können Sie auf Native Lazy Objects umstellen, was die Proxy-Generierung komplett eliminiert.

Striktere Typisierung: ORM 3 erzwingt Type-Hints für alle Entity-Properties. Untypisierte Properties (private $name; statt private string $name;) werden nicht mehr akzeptiert. Für gut gepflegte Codebases ist das kein Problem. Für Legacy-Code mit Hunderten von Entities kann das umfangreiches Refactoring bedeuten.

Der Compatibility Layer: Schrittweise migrieren

Was die Dokumentation nicht prominent genug platziert: Doctrine bietet einen Compatibility Layer, der eine schrittweise Migration ermöglicht. Sie müssen nicht alle Entities auf einmal umstellen. Der Weg sieht so aus:

Zuerst aktualisieren Sie auf die neueste ORM-2.20.x-Version und beheben alle Deprecation-Warnings. Jede Warning entspricht einer Stelle, die in ORM 3 brechen wird. Doctrine hat die Deprecation Messages bewusst so formuliert, dass sie den ORM-3-Replacement beschreiben.

Dann upgraden Sie DBAL auf Version 4. DBAL 4 funktioniert mit ORM 2.20.x (seit der Forward-Compatibility-Policy). Das reduziert den "Big Bang" auf den eigentlichen ORM-Wechsel. In der Praxis funktioniert das gut, weil DBAL-Änderungen (Connection API, Schema API, Type System) unabhängig vom ORM-Mapping sind.

# Schrittweiser Migrations-Pfad
# Phase 1: Deprecations auf ORM 2.20.x fixen
$ php bin/console debug:container --deprecations
$ vendor/bin/phpstan analyse --level 8  # Typfehler finden

# Phase 2: DBAL 4 Upgrade (kompatibel mit ORM 2.20.x)
$ composer require doctrine/dbal:^4.0

# Phase 3: ORM 3 Upgrade
$ composer require doctrine/orm:^3.6
# Jetzt Annotations → Attributes, Flush-Refactoring, Typ-Fixes

# Phase 4: Vorbereitung auf ORM 4 (optional, PHP 8.4+)
# Native Lazy Objects aktivieren (seit ORM 3.4)

Was auf den ersten Blick einfach wirkt, hat in Production Implikationen für die Deployment-Pipeline. Jede Phase sollte als eigenständiges Release deployed und getestet werden. Besonders Phase 3 (der eigentliche ORM-Wechsel) erfordert vollständige Regressionstests der Datenbank-Operationen. Wie ich im PHP-JIT-Artikel beschrieben habe, sind stille Berechnungsfehler der Worst Case. Das gilt auch für ORM-Migrationen: Ein falsch gemapptes Entity-Property erzeugt keine Exception, nur falsche Daten.

Die Migration auf ORM 3 erfordert individuelle Analyse, abhängig von Ihrer Codebase-Größe und der Mapping-Strategie. → Migrations-Beratung anfragen

Praxis-Perspektive: Was funktioniert, was nicht?

Warum stockt die ORM-3-Adoption?

25 bis 30% Adoption nach zwei Jahren ist wenig. Die Gründe, die ich in der Praxis sehe, sind größtenteils organisatorisch, nicht technisch:

Abhängigkeits-Kaskade: Viele Projekte können nicht einfach ORM 3 installieren, weil Third-Party-Bundles (Sonata, EasyAdmin, API Platform älterer Versionen) noch auf ORM 2.x festgenagelt sind. Die Migration erfordert, dass alle Dependencies mitmachen.

"Es funktioniert doch": Solange ORM 2.x Bug-Fixes erhielt, gab es keinen dringenden Grund zu migrieren. Seit März 2026 gilt die Restricted Policy. Der Druck steigt.

Flush-Änderung als Blocker: Das Entfernen von Single-Entity-Flush ist der häufigste Migration-Blocker. Projekte mit gewachsenen Service-Layern, die gezielt einzelne Entities flushen, brauchen strukturelles Refactoring. Das ist aufwändig und riskant.

Was viele unterschätzen: DBAL 4 (die Datenbank-Abstraktionsschicht unter ORM 3) hat eine deutlich höhere Adoptionsrate von rund 60%. Das zeigt, dass die Datenbank-Schicht leichter zu migrieren ist als der ORM-Kern. Agenturen, die die Migration schrittweise angehen wollen, können zuerst auf DBAL 4 upgraden und dann ORM 3 nachziehen.

Aufwandseinschätzung: Was kostet die Migration realistisch?

Das hängt von drei Faktoren ab: Anzahl der Entities, Umfang der Custom-Repository-Logik und dem Einsatz von Single-Entity-Flush.

Für ein typisches Agentur-Projekt mit 20 bis 50 Entities, Standard-Repository-Methoden und keinem Single-Entity-Flush: Der Aufwand liegt bei ein bis zwei Tagen für einen erfahrenen Symfony-Entwickler. Annotations zu Attributes ist größtenteils mechanisch (Rector kann das automatisieren), die DBAL-4-Migration ist überschaubar.

Für ein gewachsenes Projekt mit 100+ Entities, Custom DQL, Event-Listenern und Single-Entity-Flush: Mehrere Tage bis eine Woche, inklusive Regressionstests. Der Flush-Umbau ist der aufwändigste Teil, weil er die Business-Logik betrifft, nicht nur die Datenbank-Schicht.

Für Projekte mit externen Bundle-Dependencies (Sonata Admin, alte EasyAdmin-Versionen, Custom-Bundles): Addieren Sie die Bundle-Update-Zeit. Manche Bundles unterstützen ORM 3 erst seit kürzlich, manche noch gar nicht. Ein Dependency-Check mit composer why-not doctrine/orm:^3.6 zeigt sofort, wo die Blocker liegen.

Ein Anti-Pattern, das ich regelmäßig sehe: Teams beginnen die Migration, stoßen auf eine blockierende Bundle-Dependency und brechen ab. Der bessere Ansatz: Zuerst den Dependency-Check machen, dann alle Bundle-Updates durchführen, dann erst die ORM-Migration starten. Die Reihenfolge entscheidet über Erfolg oder Frustration.

Shopware-Projekte: Sonderfall beachten

Ein Punkt, der in der allgemeinen Doctrine-Diskussion oft untergeht: Shopware 6.7+ bringt seine eigene Doctrine-Version mit. Shopware steuert den Doctrine-Upgrade-Pfad für seine Nutzer. Wer Shopware-Plugins entwickelt, kann nicht einfach auf ORM 3 upgraden, ohne die Kompatibilität mit der von Shopware bereitgestellten Doctrine-Version zu prüfen.

Als Symfony-Entwickler mit Fokus auf Shopware und KMU-Projekte sehe ich hier regelmäßig Konflikte: Plugin-Entwickler, die ORM-3-Features nutzen wollen, aber an die Shopware-Version gebunden sind. Die Empfehlung: Für Shopware-Plugins bleiben Sie auf der Doctrine-Version, die Shopware vorgibt. Für eigenständige Symfony-Projekte migrieren Sie auf ORM 3.x.

Strategische Empfehlungen: Entscheidungsmatrix

Welche Versionsstrategie ist die richtige?

Legacy-Projekte auf ORM 2.x (kein aktives Feature-Development): Bleiben Sie auf ORM 2.x, aber fixieren Sie auf 2.20.x und beheben Sie alle Deprecation-Warnings. Planen Sie die Migration auf ORM 3.x erst, wenn Sie ohnehin größere Änderungen an der Applikation vornehmen. Der Aufwand lohnt sich nicht für Projekte im reinen Wartungsmodus.

Aktive Projekte auf ORM 2.x (laufendes Feature-Development): Migrieren Sie jetzt. Zuerst DBAL 4, dann ORM 3.x. Nutzen Sie das Zeitfenster bis Februar 2027, um die Migration in den regulären Entwicklungszyklus einzubetten. Jede neue Entity direkt mit Attributes statt Annotations schreiben.

Greenfield-Projekte (neuer Start): ORM 3.6.3 mit PHP 8.4. Keine Diskussion. Wer heute ein neues Projekt auf ORM 2.x startet, baut technische Schulden vom ersten Tag an.

Shopware-Projekte: Folgen Sie der Shopware-Vorgabe. Prüfen Sie bei jedem Shopware-Update, ob sich die Doctrine-Version geändert hat. Für Custom-Code außerhalb von Shopware-Plugins: ORM 3.x.

ORM 4.0 abwarten? Nein. ORM 4.0 erfordert PHP 8.4 und Native Lazy Objects. Es ist kein Upgrade-Pfad von 2.x auf 4.0 geplant. Die Migration geht 2.x → 3.x → 4.x. Wer auf 4.0 wartet, muss trotzdem erst auf 3.x migrieren.

Welche Strategie für Ihr Portfolio die richtige ist, hängt von der Anzahl Ihrer Projekte und deren Lebenszyklus ab. → Lassen Sie uns das gemeinsam evaluieren

Zusammenfassung und Ausblick

Die Doctrine ORM Versionslandschaft erfordert 2026 eine bewusste Strategie. Die wichtigsten Takeaways:

ORM 2.x ist im Restricted Maintenance Mode seit März 2026. Nur noch PHP-Kompatibilität, Security-Fixes und Forward-Kompatibilität. EOL mindestens Februar 2027.

ORM 3.6.3 ist stabil und Production-ready. Für neue Projekte die einzige sinnvolle Wahl. Für bestehende Projekte der empfohlene Migrationspfad.

Die Adoption stockt bei 25 bis 30%, hauptsächlich wegen organisatorischer Hürden (Third-Party-Dependencies, Flush-Änderung, "es funktioniert doch"). Der Druck steigt mit der Restricted Policy.

ORM 4.0 kommt Ende 2026/Anfang 2027 mit PHP 8.4 Pflicht und Native Lazy Objects. Es gibt keinen direkten 2.x→4.0 Pfad. Die Reihenfolge ist 2.x→3.x→4.x.

Shopware-Projekte haben einen Sonderstatus: Die Doctrine-Version wird von Shopware vorgegeben. Unabhängige Symfony-Projekte sollten eigenständig auf ORM 3.x migrieren.

Die nächsten Monate werden zeigen, wie die Doctrine-Community die Adoption beschleunigt. Der für Herbst 2026 geplante ORM-4.0-Hackathon wird weitere Klarheit über den Zeitplan bringen. Für Agenturen gilt: Wer jetzt auf ORM 3.x migriert, ist auf der sicheren Seite, egal ob ORM 4.0 Ende 2026 oder erst 2027 kommt.

Doctrine-Migrationsstrategie für Ihr Portfolio

Wie viele Projekte laufen auf ORM 2.x? Welche Dependencies blockieren die Migration? Wo lohnt sich der Aufwand, wo nicht? In einem kostenlosen Erstgespräch analysiere ich Ihr Projekt-Portfolio und gebe eine realistische Aufwandseinschätzung pro Projekt.

→ Doctrine-Migrations-Analyse anfragen

Dennis Schwenker-Sanders ist PHP & Symfony-Entwickler mit Fokus auf Doctrine-Migrationen, Architektur-Entscheidungen und technische Strategieberatung für deutsche Agenturen und KMU. Er begleitet Teams bei der systematischen Modernisierung ihrer PHP-Datenbank-Schichten.

Artikel teilen: