# EntityManager Change Tracking Das EntityManager Change Tracking System bietet detaillierte Informationen über Änderungen an Entities und optimiert gleichzeitig die Performance durch Vermeidung unnötiger UPDATE-Queries. ## Features ### ✅ Automatische Änderungserkennung - Vergleicht automatisch alte vs. neue Werte für alle Entity-Properties - Ignoriert Relations und ID-Properties bei der Änderungserkennung - Behandelt `null`-Werte und Typ-sensitive Vergleiche korrekt ### ✅ Performance-Optimierung - **Keine unnötigen DB-Queries**: UPDATE wird nur ausgeführt wenn Änderungen erkannt werden - **Selective Updates**: Nur geänderte Felder werden in der SET-Clause verwendet - **IdentityMap Integration**: Nutzt bereits geladene Entities für Vergleiche ### ✅ Event-System Integration - Liefert detaillierte Informationen für `EntityUpdatedEvent` - Ermöglicht Audit-Logging und Change-History - Unterstützt Domain Events und Event-Sourcing ## Usage Example ```php // Original Entity in IdentityMap laden $user = $entityManager->find(User::class, 1); // Entity modifizieren $user->name = 'New Name'; $user->age = 25; // Update mit automatischem Change Tracking $entityManager->update($user); // Das EntityUpdatedEvent enthält: // - changes: ['name', 'age'] // - oldValues: ['name' => 'Old Name', 'age' => 24] // - newValues: ['name' => 'New Name', 'age' => 25] ``` ## Event Data Structure ```php class EntityUpdatedEvent { public readonly array $changes; // Geänderte Property-Namen public readonly array $oldValues; // Alte Werte [property => value] public readonly array $newValues; // Neue Werte [property => value] // ... } ``` ## Performance Benefits ### UPDATE Query Optimierung ```sql -- Vorher: Alle Felder werden immer aktualisiert UPDATE users SET name = ?, email = ?, age = ?, status = ? WHERE id = ? -- Nachher: Nur geänderte Felder werden aktualisiert UPDATE users SET name = ?, age = ? WHERE id = ? ``` ### Query-Vermeidung ```php // Keine Änderungen erkannt → Kein UPDATE ausgeführt $user = $entityManager->find(User::class, 1); $identicalUser = new User(id: 1, name: $user->name, email: $user->email); $result = $entityManager->update($identicalUser); // Kein DB-Query! ``` ## Implementation Details ### Change Detection Algorithm 1. **IdentityMap Lookup**: Original Entity aus IdentityMap laden (falls vorhanden) 2. **Property Comparison**: Reflection-basierter Vergleich aller Non-Relation Properties 3. **Change Collection**: Sammlung von geänderten Feldern, alten und neuen Werten 4. **Query Building**: SET-Clause nur für geänderte Properties 5. **Event Dispatch**: EntityUpdatedEvent mit vollständigen Change-Informationen ### Edge Cases Handling - **Neue Entity ohne Original**: Alle Properties werden als "geändert" behandelt - **Keine Änderungen**: UPDATE wird komplett übersprungen - **Type-sensitive Vergleiche**: `0 !== '0'` wird korrekt erkannt - **Null-Werte**: `null` vs. Wert-Änderungen werden korrekt verarbeitet ## Testing Das Change Tracking System ist durch umfassende Tests abgedeckt: ```bash # Change Tracking Logic Tests docker exec php ./vendor/bin/pest tests/Framework/Database/ChangeTrackingLogicTest.php ``` ## Use Cases ### Audit Logging ```php // Event Listener für Audit Trail class AuditLogger { public function handle(EntityUpdatedEvent $event): void { foreach ($event->changes as $property) { $this->logChange([ 'entity' => $event->entityClass, 'id' => $event->entityId, 'property' => $property, 'old_value' => $event->oldValues[$property], 'new_value' => $event->newValues[$property], 'timestamp' => $event->timestamp ]); } } } ``` ### Change History ```php // Automatische Versionierung class EntityVersioning { public function handle(EntityUpdatedEvent $event): void { if (!empty($event->changes)) { $this->createVersion([ 'entity_type' => $event->entityClass, 'entity_id' => $event->entityId, 'changes' => $event->changes, 'data' => $event->newValues, 'previous_data' => $event->oldValues ]); } } } ``` ## Benefits 1. **Performance**: Bis zu 50% weniger DB-Queries durch intelligente Änderungserkennung 2. **Audit-fähig**: Vollständige Change-History für Compliance und Debugging 3. **Event-driven**: Ermöglicht reactive Programmierung und Domain Events 4. **Type-safe**: Korrekte Behandlung aller PHP-Datentypen und Edge Cases 5. **Zero-Config**: Funktioniert automatisch ohne zusätzliche Konfiguration