在Doctrine2中保存单个实体

时间:2012-06-11 12:32:09

标签: doctrine-orm

我可以在Symfony中保存单个实体,而不会刷新所有更改吗? E. g。

$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的文档(根本没有使用它,即使它没有标记为内部函数)。这是一个好主意吗?它有危险吗?

2 个答案:

答案 0 :(得分: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中)。

答案 1 :(得分: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中加载了2个以上的实体。在这种情况下,如果您detach($entity2)可能是具有第一个flush()的EntityManager也将保存到数据库中的其他已加载实体的修改。

因此,必须小心使用此解决方案。

另一个解决方案可能是使用clear():这会分离所有托管实体。它实际上类似于刚刚初始化的新EntityManager。

我最近使用了这个最后的解决方案,只保存了一些实体的部分数据,这些实体有一些必须保存的相关实体。

所以,我:

  1. 首先清除了实体经理;
  2. 然后重新加载我正在更新的实体;
  3. 做出相关修改;
  4. 刷新EntityManager
  5. 制作非常具体的刷新可能有点复杂,而且,确实有一种方法只能部分保存实体会非常有用。

    但目前这些方法是唯一可行的方法。