2013-03-13 4 views
6

현재 "더티"버전 (속성의 일부가 변경된 객체, 아직 지속되지 않음) 및 "원래"버전 (데이터는 데이터베이스에 계속 남아 있습니다).Doctrine2 Entites - "더티 (dirty)"객체와 데이터베이스의 객체를 비교할 수 있습니까?

내 가정은 "더러운"개체를 가질 수 있었고 DB에서 새 개체를 가져 와서 두 개체를 비교할 수있었습니다. 예를 들어 :

$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))); 
} 

하지만 내 경험

는 $ 엔티티와 $ db_entity는 항상 같은 객체 (및 양식 $ 요청 바인드 후, $ 엔티티와 동일한 데이터를 가지고). 비교를 위해 "더티"버전과 함께 $ 엔티티의 새 버전을 구할 수있는 방법이 있습니까? 필자가 보아온 솔루션은 폼 바인딩이 일어나기 전에 필요한 모든 데이터를 가져 오지만, 그 제한이 없다.

업데이트 : 분명히하기 위해 나는 엔티티의 속성뿐만 아니라 엔티티의 관련 컬렉션에 대해서도 살펴 보았습니다.

+0

내가 특별히 부탁 ICAN은 Symfony2 양식 모음에서 항목을 제거에 더 나은 솔루션을 만들 수 있도록.[현재 해결책] (http://symfony.com/doc/2.0/cookbook/form/form_collections.html#templates-modifications) 바인드가 너무 제한적으로 보이기 전에 값을 가져 와서 좋은 함수를 만드는 데 도움이되지 않는 곳 처리해. –

+0

이것은 http://stackoverflow.com/questions/9057558/any-built-in-way-to-all-the-changed-fields-in-doctrine-2/9057705#9057705 – Ocramius

+0

의 사본입니다. 엔터티 자체에 대한 변경 사항을 찾는 것이 아니라 엔터티 내의 관련 컬렉션을 변경하기 때문에 내 질문의 범위를 확장하십시오. UnitOfWork를 사용하면 이전의 작업에만 도움이됩니다. 그러나 다른 find()를 수행하기 전에 $ em-> clear()를 사용하는 Alex의 제안처럼 보이는 것은 내가 찾고있는 "신선한"엔터티를 얻습니다. –

답변

5

.. 그래서 ... 당신은 $db_entityflush() 전에


를 검색 할 수 있습니다 : 당신은 수행하여 이러한 정보를 얻을 수 있습니다
  1. 당신이 원하는 것이 확실하지 않지만 persist 대신 merge을 사용할 수도 있습니다.

    • merge은 수정 된 개체를 반환 - ID 생성 및
    • persist
    • 을 살고 있고이 인스턴스
  2. 을 수정하는 것입니다 당신이 개체가 수정 갖고 싶어하고 flush 전에 사용하지 persisted합니다. 당신이 $em->clear()

    • flush 모든 변경 사항 (모든 dirty 객체)
    • clear
    • 메모리 캐시를 삭제됩니다 커밋되어 있지 않았기 때문에

    • EntityManager 당신에게 동일한 인스턴스을주고있다. 그래서 당신 find(..., $id), 당신은 새로운 인스턴스를 얻을 것이다
  3. clone는 당신을 위해 키워드를 사용하고 있습니까? 같은 예에서 :

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

그리고 당신은이 부분을 읽어보십시오 : Implementing Wakeup or Clone

+0

들려요, 저의 예가 좋지 않아 업데이트했습니다. $ db_entity는 persist() 및 flush() 전에 검색되어야합니다. 그렇게 할 때에도 $ entity와 $ db_entity는 동일합니다. –

+0

내 게시물에 다른 솔루션을 추가했습니다 ('복제본'부분) – Alex

9

Doctine의 UnityOfWork를 통해 엔티티에서 변경된 사항을 얻을 수 있습니다. 이것은 매우 간단합니다 : 당신이 엔티티를 영속화 한 후에, Doctrine은 데이터베이스에서 무엇을 업데이트해야하는지 알고 있습니다. 당신이 데이터베이스 (가 최선을 다하고) 일어나는 $em를 세척 한 후

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

컨트롤러에서 이것을 호출 할 수 있습니까? 때문에이 시도 할 때 내 엔터티 (그냥 빈 배열)에 대한 변경 내용을 표시하지 않습니다. –

+2

이 게시물에서이 방법과 관련된 경고를 읽으십시오. http://stackoverflow.com/questions/9057558/is-there-a-built-in-way-to-get-all-of-the-changed -updated-fields-in-a-doctrine-2 – tiho