2013-03-13 3 views
6

Ist es möglich, den Status eines Entitätsobjekts zwischen der aktuellen "schmutzigen" Version zu vergleichen (ein Objekt, das einige seiner Eigenschaften verändert hat, noch nicht beibehalten) und die "ursprüngliche" Version (die Daten noch in der Datenbank).Doctrine2-Entitäten - Ist es möglich, ein "schmutziges" Objekt mit einem aus der Datenbank zu vergleichen?

Meine Annahme war, dass ich ein "schmutziges" Objekt haben könnte, dann ziehe ein neues aus der DB und vergleiche die beiden. Zum Beispiel:

$entity = $em->getRepository('MyContentBundle:DynamicContent')->find($id); 

$editForm = $this->createContentForm($entity); 
$editForm->bind($request); 

if ($editForm->isValid()) { 
    $db_entity = $em->getRepository('MyContentBundle:DynamicContent')->find($id); 

    // compare $entity to $db_entity 

    $em->persist($entity); 
    $em->flush(); 

    return $this->redirect($this->generateUrl('content_edit', array('id' => $id))); 
} 

Aber in meiner Erfahrung $ Einheit und $ db_entity ist immer das gleiche Objekt (und hat die gleichen Daten wie $ Einheit, nach der Form $ Anfrage binden). Gibt es eine Möglichkeit, eine neue Version der Entität $ neben der "schmutzigen" Version zum Vergleich zu bekommen? Die Lösungen, die ich gesehen habe, ziehen die benötigten Daten, bevor die Formbindung stattfindet, aber ich möchte diese Einschränkung nicht haben.

Update: Um zu klären, ich suche nicht nur nach Änderungen an den Eigenschaften der Entitäten, sondern auch die damit verbundenen Sammlungen von Entitäten.

+0

Ich frage speziell so Ican eine bessere Lösung zu Entfernen von Elementen aus einer Symfony2 Form Sammlung.[Die aktuelle Lösung] (http://symfony.com/doc/2.0/cookbook/form/form_collections.html#templates-modifications) wo Sie die Werte vor der Bindung ziehen, scheint zu einschränkend und nicht förderlich, um eine nette Funktion zu machen handle es. –

+0

Dies ist ein Duplikat von http://stackoverflow.com/questions/9057558/any-built-in-way-to-get-all-the-changed-fields-in-doctrine-2/9057705#9057705 – Ocramius

+0

ich sollte Erweitern Sie den Umfang meiner Frage, da ich nicht nur nach Änderungen an der Entität selbst suche, sondern auch nach den zugehörigen Sammlungen innerhalb der Entität. Mit UnitOfWork hilft nur mit ersterem. Allerdings sieht es aus wie Alex 'Vorschlag, $ em-> clear() zu verwenden, bevor man einen anderen find() findet, um die "frische" Entität zu erhalten, nach der ich suche. –

Antwort

5

Nachdem Sie die $em spülen es passiert (es verpflichtet ist) in der Datenbank .. so ... Sie könnten die $db_entity vor flush()


abrufen möchten
  1. Ich bin mir nicht sicher, was Sie wollen .. aber Sie können auch merge anstelle von persist verwenden.

    • merge kehrt das Objekt modifiziert - ID generiert und gefassten
    • persist Instanz
  2. Wenn Sie das Objekt geändert haben wird, zu modifizieren wollen und persisted es nicht vor flush verwenden.

  3. EntityManager wird Ihnen die gleiche Instanz geben, weil Sie $em->clear()
    • flush ist, alle Änderungen commiting (alle dirty Objekte)
    • clear klart Cache-Speicher nicht. Wenn Sie also find(..., $id), erhalten Sie eine neue Instanz
  4. Ist clone Schlüsselwort für Sie arbeiten? wie in diesem Beispiel:

$entity = $em->find('My\Entity', $id); 
$clonedEntity = clone $entity; 

Und Sie mögen vielleicht auch dies lesen: Implementing Wakeup or Clone

+0

Hoppla, mein Beispiel war schlecht und ich habe es aktualisiert. Die $ db_entity sollte vor persist() und flush() abgerufen werden. Selbst wenn dies geschieht, sind $ entity und $ db_entity identisch. –

+0

hat meinem Beitrag eine andere Lösung hinzugefügt (der 'Klon'-Teil) – Alex

9

Durch Doctie's UnityOfWork können Sie herausfinden, was sich an der Entität geändert hat. Es ist ganz einfach: Nachdem Sie die Entität beibehalten haben, weiß Doctrine, was in der Datenbank aktualisiert werden soll. Sie können diese Informationen erhalten, indem Sie:

// Run these AFTER persist and BEFORE flush 
$uow = $em->getUnitOfWork(); 
$uow->computeChangeSets(); 
$changeset = $uow->getEntityChangeSet($entity); 
+1

Kann dies in einem Controller aufgerufen werden? Denn wenn ich dies versuche, zeigt es keine Änderungen für meine Entity (nur leeres Array). –

+2

Stellen Sie sicher, dass Sie die Warnung zu dieser Methode in diesem Post lesen: http://stackoverflow.com/questions/9057558/is-there-a-built-in-way-to-get-all-of-the-changed -updated-fields-in-a-doctrine-2 – tiho

Verwandte Themen