2011-10-31 27 views
21

Chcę móc pobrać istniejącą wersję obiektu, aby móc go porównać z najnowszą wersją. Na przykład. Edycja pliku, chcę wiedzieć, czy wartość zmieniła się od bycia w DB.Jak zatrzymać Doctrine 2 przed buforowaniem wyniku w Symfony 2?

$entityManager = $this->get('doctrine')->getEntityManager(); 
    $postManager = $this->get('synth_knowledge_share.manager'); 

    $repository = $entityManager->getRepository('KnowledgeShareBundle:Post'); 
    $post = $repository->findOneById(1); 

    var_dump($post->getTitle()); // This would output "My Title" 
    $post->setTitle("Unpersisted new title"); 

    $existingPost = $repository->findOneById(1); // Retrieve the old entity 

    var_dump($existingPost->getTitle()); // This would output "Unpersisted new title" instead of the expected "My Title" 

Czy ktoś wie, jak mogę obejść to buforowanie?

Odpowiedz

40

To normalne zachowanie.

Doctrine przechowuje odniesienie do pobranych elementów w EntityManager, dzięki czemu może zwrócić obiekt poprzez jego identyfikator bez wykonywania innego zapytania.

można zrobić coś takiego:

$entityManager = $this->get('doctrine')->getEntityManager(); 
$repository = $entityManager->getRepository('KnowledgeShareBundle:Post'); 
$post = $repository->find(1); 

$entityManager->detach($post); 

// as the previously loaded post was detached, it loads a new one 
$existingPost = $repository->find(1); 

jednak mieć świadomość, że jako podmiot $ post był indywidualny, należy użyć metody -> merge(), jeśli chcesz, aby utrzymywać go ponownie.

+4

Pyszne, "odczep" jest idealne. –

+10

Dzięki za to. Szybka wskazówka - jeśli chcesz odłączyć wszystkie jednostki (np. W testach nieizolowanych), możesz użyć '$ entityManager-> clear()'. – richsage

+0

Kolejną rzeczą wartą obejrzenia jest to, czy masz otwartą transakcję. Jeśli wykonałeś '$ entityManager-> beginTransaction()', upewnij się, że zamknąłeś transakcję (np. '$ EntityManager-> rollback()') przed próbą wyczyszczenia menedżera encji. Otwarta transakcja wymusi spójny, dlatego nie aktualizowany, widok bazy danych. – stanhope

8

Można również użyć metody refresh, która odświeża trwały stan obiektu z bazy danych, zastępując wszelkie lokalne zmiany, które nie zostały jeszcze utrwalone. Coś jak:

$entityManager = $this->get('doctrine')->getEntityManager(); 
$repository = $entityManager->getRepository('KnowledgeShareBundle:Post'); 
$post = $repository->find(1); 

$entityManager->refresh($post); 

teraz $ post zawiera ostatnią wersję z bazy danych.

+1

Ty jesteś ratownikiem! –

+0

jest to bardzo przydatne i wydaje się mało znane. Warto zwrócić uwagę na kaskadę = "REFRESH" na powiązanych jednostkach, aby ładnie działała – DevDonkey