2012-03-06 3 views
2

У меня настроен прослушиватель доктрины, который запускается в разных действиях базы данных и создает объект журнала и вставляет его в базу данных.Вставка элемента в приемник доктрины

class FOO { 
// [...] 
public function onFlush(OnFlushEventArgs $args) 
{ 
    foreach ($args->getEntityManager()->getUnitOfWork()->getScheduledEntityUpdates() as $entity) { 
       $this->createLog('edit', $entity); 
    } 
} 


private function createLog($action, $entity) 
{ 
     if ($entity instanceof Log) { 
      return; 
     } 
     $log = new Log; 
     $log->setAction($action); 
     $log->setTime(new \DateTime); 
     $log->setForeignId($entity->getId()); 
     $log->setUser($this->getUser()); 
     $t   = explode('\\', get_class($entity)); 
     $entity_class = strtolower(end($t)); 
     $log->setEntity($entity_class); 
     $this->getEntityManager()->persist($log); 
    } 
// [...] 
} 

Когда я обновить объект, я получаю следующее сообщение об ошибке:

SQLSTATE[HY093]: Invalid parameter number: no parameters were bound

В профилировщике я вижу этот вопрос:

INSERT INTO vvg_logs (action, entity, foreign_id, user_id, time) VALUES (?, ?, ?, ?, ?)

Parameters: { }

Как я могу решить эту проблему?

UPDATE Вот моя новая тема подключения к этому вопросу: LINK

+0

Кажется, вопрос, который вы ссылаетесь были удалены. Не могли бы вы предоставить дополнительную информацию о том, как вы это решили? – cellulosa

ответ

5

Потому что, когда onFlush называется, все изменения уже вычислили, и вам необходимо обновить их, если вы измените объект или создать новый объект ,

$em = $this->getEntityManager(); 
$uow = $em->getUnitOfWork(); 
$logMetadata = $em->getClassMetadata('Your\LogClass'); 
... 
$em->persist($log); 
$uow->computeChangeSet($logMetadata, $log); 

Для postPersist:

$em = $this->getEntityManager(); 
$uow = $em->getUnitOfWork(); 
$log = new Log; 
... 

$logMetadata = $em->getClassMetadata('Your\LogClass'); 
$className = $logMetadata->name; 
$persister = $this->getEntityPersister($className); 
$persister->addInsert($log); 
$uow->computeChangeSet($classMeta, $logEntry); 
$postInsertIds = $persister->executeInserts(); 

if ($postInsertIds) { 
    foreach ($postInsertIds as $id => $entity) { 
     $idField = $logMetadata->identifier[0]; 
     $logMetadata->reflFields[$idField]->setValue($entity, $id); 
     $this->addToIdentityMap($entity); 
    } 
} 
+0

Работает отлично, спасибо вам большое! –

+0

Как я могу продолжить новый вход в систему для прослушивания postPersist? Проблема в том, что в методе фиксации UnitOfWork сначала происходят вставки, но когда мой слушатель запущен, вставки завершены, поэтому мой журнал не будет вставлен. Я попытался вызвать метод фиксации из моего прослушивателя, но это заставляет другие объекты сущностей быть вставлены дважды. То, что я хотел бы достичь, - это вспомнить фиксацию после того, как все будет сделано. Если вы знаете альтернативное решение, это тоже хорошо. –

+1

@ DavidFrank обновлен. Я думаю, вам не нужно снова вызывать метод фиксации. – meze

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