Doctrine2:多次调用flush

时间:2015-10-08 09:03:25

标签: php symfony doctrine-orm doctrine

我对Symfony 2.3上的Doctrine和Entities有疑问。

根据"文档书"章节"数据库和学说>保存相关实体" (查看此处的示例:http://symfony.com/doc/current/book/doctrine.html) 该示例同时在产品和类别表中创建一个新行,并将product.category_id值与" id"相关联。新类别项目。

问题是Action Controller会在调用时随时创建新产品和新类别!

为了创建一个新产品并将其category_id与现有的类别ID相关联(我通过url进行了测试传递参数:/ web / store / create / newproduct / Kayak / 12

这是routing.yml路线

acme_store_create_product_by_category:
path:     /create/newproduct/{name}/{categoryId}
defaults: { _controller: AcmeStoreBundle:Default:createProduct }

我做了类似这样的事情似乎工作正常:

public function createProductAction($name, $categoryId)
{   
    $em = $this->getDoctrine()->getManager();

    if ( $em->getRepository("AcmeStoreBundle:Category")->findOneById($categoryId) ) {

        $product = new Product();

        $product->setName($name);
        $product->setPrice(220);
        $product->setDescription("This is just a test");

        $em->persist($product);

        $em->flush();

        $newproduct = $em->getRepository("AcmeStoreBundle:Product")->find($product->getId());
        /** Create new product and populate $newproduct with its data */


        $repository = $em->getRepository("AcmeStoreBundle:Category")->find($categoryId);

        $newproduct->setCategory($repository);

        $em->persist($newproduct);

        $em->flush();
        /** Update the id_category field of the new product with parameter $categoryId */

        //exit(\Doctrine\Common\Util\Debug::dump($product));

        return new Response('Create product ' . $name . ' with category id ' . $categoryId);

    } else {

        return new Response('It doesn\'t exists any category with id ' . $categoryId);
    }
}

我在这种情况下的疑问是:在同一个Action中两次调用flush()方法是一个好习惯吗?在这种情况下,我想创建一个新产品,从"列表框中选择相关类别"。

提前谢谢!

1 个答案:

答案 0 :(得分:2)

我认为这主要取决于您的应用领域。如果您运行flush两次,则意味着您正在运行两笔交易。在第一个中你坚持产品,在第二个产品中是一个类别。因此,如果第一笔交易失败(让我们说您在产品名称上有一个唯一的密钥,并且您尝试保留具有相同名称的产品,以便获得重复的密钥异常),那么问问自己是否& #39;可以继续并坚持一个类别。我不认为我们可以在这里轻松回答,因为我认为这取决于您的应用程序逻辑,该端点应该做什么,如果您最终拥有产品而不是类别会发生什么,反之亦然。< / p>

您还应该考虑,如果您在第一次交易中遇到异常,您的代码将无法处理该错误,因此第二次交易将失败。当像重复键这样的异常发生时,所有实体都被分离,并且实体管理器不再知道如何管理事物。因此,您必须重置它,否则您将遇到EntityManager is closed问题。

try {
    // first transaction
    $entityManager->persist($entityOne);
    $entityManager->flush();
} catch (\Exception $e) {
    /* ... handle the exception */ 
    $entityManager->resetManager();
}

// now we can safely run a second transaction here

我希望这能回答你的问题: - )

相关问题