如何检查Doctrine 2中是否更改了实体?

eag*_*tor 28 php doctrine doctrine-orm

我需要检查持久化实体是否已更改并需要在数据库上更新.我所做的(并没有奏效)如下:

$product = $entityManager->getRepository('Product')->find(3);
$product->setName('A different name');

var_export($entityManager->getUnitOfWork()->isScheduledForUpdate($product));
Run Code Online (Sandbox Code Playgroud)

该代码始终打印false,我也在检查工作单元之前尝试刷新,但没有工作.

有人有建议吗?

Ser*_*rgi 24

我首先要检查你的setName函数实际上在做什么($ this-> name = $ name ...)如果它已经工作了,那么你可以在services.yml上定义一个事件监听器,当它被触发时你打电话给同花顺.

entity.listener:
  class: YourName\YourBundle\EventListener\EntityListener
  calls:
    - [setContainer,  ["@service_container"]]
  tags:
    - { name: doctrine.event_listener, event: onFlush }
Run Code Online (Sandbox Code Playgroud)

然后定义EntityListener

namespace YourName\YourBundle\EventListener;

use Doctrine\ORM\Event;
use Symfony\Component\DependencyInjection\ContainerAware;

class EntityListener extends ContainerAware
{   

    /**
     * Gets all the entities to flush
     *
     * @param Event\OnFlushEventArgs $eventArgs Event args
     */
    public function onFlush(Event\OnFlushEventArgs $eventArgs)
    {   
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        //Insertions
        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            # your code here for the inserted entities
        }

        //Updates
        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            # your code here for the updated entities
        }

        //Deletions
        foreach ($uow->getScheduledEntityDeletions() as $entity) {
            # your code here for the deleted entities
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要知道哪些实体正在被更改,但在将它们保存到数据库之后对它们执行某些操作,只需将更改的实体存储在私有数组中,然后定义一个从该数组中获取实体的onFlush事件.

顺便说一句,要触发此类事件,您需要在实体上添加@ORM\HasLifecycleCallbacks.


Pie*_*NAY 12

我不需要/想要为我的案例创建听众,所以我最终得到了

$product->setName('A different name');
$uow = $entityManager->getUnitOfWork();
$uow->computeChangeSets();
if ($uow->isEntityScheduled($product)) {
    // My entity has changed
}
Run Code Online (Sandbox Code Playgroud)


And*_*son 11

如果需要访问具有旧值和新值的实体字段,您可能还需要查看PreUpdate事件.

一些例子主要取自提供的链接:

<?php
class NeverAliceOnlyBobListener
{
    public function preUpdate(PreUpdateEventArgs $eventArgs)
    {
        if ($eventArgs->getEntity() instanceof User) {
            if ($eventArgs->hasChangedField('name') && $eventArgs->getNewValue('name') == 'Alice') {
                $oldValue = $eventArgs->getOldValue('name');
                $eventArgs->setNewValue('name', 'Bob');
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Mik*_*ikl 7

Doctrine2 Docs.17.更改跟踪政策

如果您像我一样使用第三种形式(17.3.通知),您可以测试您的实体是否被更改:

$uow = $entityManager->getUnitOfWork();
$uow->computeChangeSets();
$aChangeSet = $uow->getEntityChangeSet($oEntity);
Run Code Online (Sandbox Code Playgroud)

如果没有任何改变,它将返回空白数组.

  • 在检索变更集之前不要忘记调用`$uow-&gt;computeChangeSets();`。 (3认同)