Doctrine EventListener onFlush不保存原始实体

Sha*_*kus 0 flush event-listener symfony doctrine-orm

我一直在努力解决烦人的问题.我正在尝试创建与InventoryItems过期关联的通知实体.

这些InventoryItems是为用户自动生成的,但用户可以编辑它们并单独设置它们的到期日期.保存后,如果InventoryItem具有到期日期,则生成通知实体并将其关联.因此,当实体更新时会创建这些通知实体,因此onPersist事件不起作用.

一切似乎都运行良好,并在按预期保存InventoryItems时生成通知.唯一的问题是,当第一次创建通知时,即使它已正确保存,也不会保存对InventoryItem的更改.即创建了具有正确到期日期的通知,但有效期未保存在InventoryItem上.

这是我的onFlush代码:

 public function onFlush(OnFlushEventArgs $args)
{
    $em  = $args->getEntityManager();
    $uow = $em->getUnitOfWork();
    foreach ($uow->getScheduledEntityUpdates() as $entity) {
        if ($entity instanceof NotificableInterface) {
          if ($entity->generatesNotification()){
              $notification = $this->notificationManager->generateNotificationForEntity($entity) ;
              if ( $notification ) {
                  $uow->persist($notification) ; 
              }
              $entity->setNotification($notification) ; 
              $uow->persist($entity);
              $uow->computeChangeSets();
          }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该问题仅在通知第一次与实体关联时发生,即第一次在InventoryItem上设置到期日期.在更新到期日期的后续实例中,更新将在Notification和InventoryItem上正确反映.

任何想法或建议将不胜感激.

谢谢

Ric*_*ard 5

您需要专门在新创建或更新的实体上调用computeChangeset .仅调用computeChangeSets是不够的.

    $metaData = $em->getClassMetadata('Your\NameSpace\Entity\YourNotificationEntity');
    $uow->computeChangeSet($metaData, $notification);
Run Code Online (Sandbox Code Playgroud)


Sha*_*kus 5

谢谢理查德。你为我指明了正确的方向。我需要重新计算父实体 (InventoryItem) 上的更改集才能正常工作。此外,我必须在工作单元上调用computeChangeSets以消除无效参数编号错误(例如解释的symfony2 +原则:修改`onFlush`上的子实体:“无效参数编号:绑定变量的数量不匹配令牌数量”

请注意,我最终还删除了:

if ( $notification ) {
    $uow->persist($notification) ; 
}
Run Code Online (Sandbox Code Playgroud)

这从来没有意义,因为我已经在我的实体中的关联上设置了级联持久性,并且应该自动向下级联。

我的最终解决方案是:

public function onFlush(OnFlushEventArgs $args)
{
    $em  = $args->getEntityManager();
    $uow = $em->getUnitOfWork();

    foreach ($uow->getScheduledEntityUpdates() as $entity) {
        if ($entity instanceof NotificableInterface) {
            if ($entity->generatesNotification()){
                $notification = $this->notificationManager->generateNotificationForEntity($entity) ;
                $entity->setNotification($notification) ; 
                // if ( $notification ) {
                //    $uow->persist($notification) ; 
                // }
                $metaData = $em->getClassMetadata(get_class($entity));
                $uow->recomputeSingleEntityChangeSet($metaData, $entity);
                $uow->computeChangeSets();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)