2012-06-11 2 views
4

Могу ли я сохранить единственное сущность в Symfony, не смывая все изменения? E. g.Сохранить однообъект в Doctrine2

$em = $this->getDoctrine(); 
$entity1 = $em->find('\SomeEntity', 1); 
$entity2 = $em->find('\SomeEntity', 2); 
$entity1->setFoo(1); 
$entity1->persist(); 
$entity2->setFoo(2); 
$this->saveRightNow($entity2); // entity2 is written to the DB at this point 
$em->flush(); // entity1 is written to the DB at this point 

Глядя в исходный код, кажется, я мог бы использовать Doctrine\ORM\UnitOfWork::commit:

function saveRightNow($entity) { 
    $em = $this->getDoctrine(); 
    $uow = $em->getUnitOfWork(); 
    $uow->commit($entity); 
} 

, но я не мог найти любую документацию по использованию commit этот путь (ни много использовать его на всех, даже если он не помечен как внутренняя функция). Это хорошая идея? Есть ли в этом опасности?

+1

Это, наверное, ужасная идея. Я не могу сказать больше, не понимая, какую проблему вы пытаетесь решить.Я подозреваю, что вам что-то не хватает в том, что доктрина делает для вас, и пытаются решить проблему, которая либо не существует, либо ожидается в библиотеке. – timdev

+0

В основном я хочу объекты, которые могут спасти себя, так что некоторые изменения БД можно сделать глубоко внутри кода модели, без необходимости программиста контроллера. – Tgr

+0

timdev, причина использования фиксации одного объекта: 1), чтобы избежать запуска процесса отслеживания изменений, когда-то дорогое; 2) отделить некоторые изменения сущностей в отдельной транзакции; 3) для управления порядком фиксации к db – Mikl

ответ

0

Все наши образований подклассы суперкласса называется Entity.php, который имеет такую ​​функцию:

public function save($flush = TRUE) 
{ 
    try { 
     self::getEntityManager()->persist($this); 

     if ($flush) { 
      self::getEntityManager()->flush(); 
     } 
    } catch (\Exception $e) { 
     return $e; 
    } 

    return TRUE; 
} 

Ссылки на getEntityManager могут быть поставлены с вашим любимым способом, чтобы получить EntityManager (мы экономим наш в Zend_Registry).

+0

Это делает что-то совершенно отличное от того, что описанный вопрос. Вы не можете сбросить одну сохраненную замену, не смывая все. – Tgr

0

Также, если это старый вопрос, может быть, ответ может быть полезен кому-то другому, поскольку это первый вопрос, который показывает Google.

Итак, вы не можете flush одного объекта, но вы можете detach им.

Таким образом, в вашем конкретном случае, вы можете сделать что-то вроде этого:

$em = $this->getDoctrine(); 
$entity1 = $em->find('\SomeEntity', 1); 
$entity2 = $em->find('\SomeEntity', 2); 
$entity1->setFoo(1); 
$entity2->setFoo(2); 

// At this point start the "new" code 
// So, first detach $entity2 
$em->detach($entity2); // Now the EntityManager doesn't know anymore of $entity2 
$em->flush(); // entity1 is written to the DB at this point 

// Add again $entity2 to the EntityManager 
$em->persist($entity2); 
$em->flush(); 

Очевидно, что это очень простой пример.

В реальном использовании, возможно, вы загрузили в EntityManager более двух объектов. В этом случае, также если вы detach($entity2) может быть, что EntityManager с первым flush() сохранит в базе данных также изменения, внесенные в другие загруженные объекты.

Итак, это решение должно использоваться с осторожностью.

Другим решением может быть использование clear(): это отделяет все управляемые объекты. Он действительно похож на новый EntityManager, который только что инициализирован.

Я недавно использовал последнее решение, чтобы сохранить только частичные данные объекта, которые имеют некоторые связанные объекты, которые не должны быть сохранены.

Итак, я:

  1. Сначала очистил менеджер лица;
  2. Затем перезагрузили объект, который я обновлял;
  3. Имеет соответствующие модификации;
  4. промыта EntityManager

Это может быть немного сложно из очень конкретных флеши, и, конечно, было бы очень полезно иметь метод, чтобы сохранить только частично объект.

Но на данный момент эти подходы являются единственными возможными.

Смежные вопросы