Php Doctrine2:多次调用flush

Php Doctrine2:多次调用flush,php,symfony,doctrine-orm,doctrine,Php,Symfony,Doctrine Orm,Doctrine,我有一个关于Symfony 2.3的条令和实体的问题 根据“文档手册”章节“数据库和条令>保存相关实体”(检查此处的示例:) 该示例同时在product和category表中创建新行,并将product.category_id值与新类别项的“id”关联 问题是动作控制器在任何时候被调用时都会创建一个新产品和一个新类别 为了创建一个新产品并将其类别id与现有类别id相关联(我通过如下url进行了参数测试:/web/store/create/newproduct/Kayak/12) 这是routin

我有一个关于Symfony 2.3的条令和实体的问题

根据“文档手册”章节“数据库和条令>保存相关实体”(检查此处的示例:) 该示例同时在product和category表中创建新行,并将product.category_id值与新类别项的“id”关联

问题是动作控制器在任何时候被调用时都会创建一个新产品和一个新类别

为了创建一个新产品并将其类别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);
    }
}
在这种情况下,我的疑问是:在同一个操作中调用flush()方法两次是否是一种好的做法?在这种情况下,我想创建一个新产品,从“列表框”中选择相关类别


提前谢谢你

我认为这主要取决于你的应用领域。如果您运行
flush
两次,则表示您正在运行两个事务。在第一个示例中,您将持久化一个产品,在第二个示例中,您将持久化一个类别。因此,如果第一个事务失败(假设您在产品名称上有一个唯一的密钥,并且您正试图持久化具有相同名称的产品,因此您会得到一个重复的密钥异常),那么请询问自己是否可以继续并持久化一个类别。我不认为我们可以很容易地回答这个问题,因为我认为这取决于您的应用程序逻辑,端点应该做什么,如果您最终拥有一个产品而不是一个类别,会发生什么,反之亦然

您还应该考虑,如果在第一个事务中出现异常,则代码将无法处理该错误,因此第二个事务将失败。当出现重复密钥之类的异常时,所有实体都被分离,实体管理器不再知道如何管理。因此,您必须将其重置,否则将出现

EntityManager关闭的问题

试试看{
//第一笔交易
$entityManager->persist($entityOne);
$entityManager->flush();
}捕获(\异常$e){
/*…处理异常*/
$entityManager->resetManager();
}
//现在我们可以在这里安全地运行第二个事务

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

非常感谢弗朗西斯科:-)!我目前正在进行大量的工作,以便切换到诸如方法和ORM之类的实体。它与PDO或mysqli库方法相去甚远。是的,我发布的示例只是我的一个好奇心,与Symfony文档书中的示例密切相关,当然不是一个真正的应用:-)无论如何,你的提示非常有用!我将在我的测试代码中实现它,以便在将来的案例中牢记它的帮助@FabrizioSabato:-)您是否在寻找其他信息?我这么问是因为我不确定这是否完全回答了你的问题。最好是更改问题标题,以便对来自搜索引擎的用户也有用。类似于“Doctrine2:多次调用flush”?好吧,现在我正在阅读一些关于webforms的文档以及与之相关的beahviours。我很确定这会带来更多的信息,我很乐意在这次讨论中与大家分享。好的,根据你的建议,我将更改标题。如果这回答了你的问题,你应该将其标记为已接受的答案:)