【问题标题】:Doctrine 2 - (sometimes) duplicate related entities on flush原则 2 - (有时)在刷新时重复相关实体
【发布时间】:2016-07-14 06:14:47
【问题描述】:

我有每 60 秒执行一次的 php worker。工人浏览文章并发布它们。

我有仓库:

public function findAllUnpublished()
{
    $query = $this->entityManager->createQuery('SELECT i FROM Extra\Item\Item i
            WHERE i.status = :status')
            ->setParameter('status', ItemStatusEnum::UNPUBLISHED);
    return $query->getResult();
}

和门面

public function publishUnpublished()
{
    $items = $this->cliRepository->findAllUnpublished();
    foreach ($items as $item) {
        $item->setPublish(TRUE);
        $this->entityManager->persist($item);
    }
    $this->entityManager->flush();
    $this->itemChangedObserver->notifyBatchPublished($items); // this clear cache on web server
    return $items;
}

还有被称为门面的工人

public function execute()
{
    $this->logger->logMessage(ILogger::DEBUG, 'Start publising');

    $items = $this->itemFacade->publishUnpublished();
    $itemsIds = array_map(function ($item) {
        return $item->getId();
    }, $items);
    $this->logger->logMessage(
        ILogger::DEBUG,
        'Published %d items (%s)',
        count($items),
        implode(', ', $itemsIds)
    );

    $this->logger->logMessage(ILogger::DEBUG, 'End publising');

    return IJob::OK;
}

问题是有时(不是每个回合)工作人员会在图库中复制相关图像。

文章:

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @OneToMany(targetEntity="gallery", mappedBy="article", cascade={"persist", "remove"})
 * @OrderBy({"position" = "ASC"})
 *
 */
private $gallery;

画廊:

/**
 * @var \Article
 *
 * @ManyToOne(targetEntity="Article", inversedBy="gallery")
 */
private $article;

有人遇到过这种情况吗?

【问题讨论】:

    标签: php doctrine-orm duplicates flush


    【解决方案1】:

    在现有条目上调用 EntityManager::persist() 可能会对关联产生副作用。

    所以,只需删除这一行,只保留你的同花顺:

    $items = $this->cliRepository->findAllUnpublished();
    
    foreach ($items as $item) {
        $item->setPublish(TRUE);
    }
    
    $this->entityManager->flush();
    
    // ...
    

    更多信息,look here

    编辑

    您应该使用EntityManager::merge($object) 而不是EntityManager::persist($object),例如:

    foreach ($items as $item) {
        $item->setPublish(TRUE);
        $this->entityManager->merge($item);
    }
    

    如果找不到引用,这将创建一个新条目,否则这将更新现有条目。

    更多关于merging entities

    【讨论】:

    • 没有。我已经删除了坚持,问题没有解决。如果您在已经存在的实体上调用persist,这无关紧要。它只调用监听器,仅此而已。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 2012-01-30
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多