Symfony2自定义存储库,延迟加载和代理对象

时间:2011-10-24 23:29:44

标签: repository doctrine-orm symfony dql

我在使用Symfony2中的Doctrine2从数据库中提取关系对象时遇到了一些麻烦。我有一个具有以下功能的自定义存储库:

public function getOrder($id) {
    $DQL = 'SELECT request, orderer
    FROM OrderRequestBundle:OrderRequest request
    JOIN request.orderer orderer
    WHERE request.id = :id';

    $query = $this->getEntityManager()->createQuery($DQL)
                ->setParameter('id', $id)
                ->setMaxResults(1);
    return $query->getResult();
}

...但由于某种原因,当我运行此函数时,我得到一个OrderRequest对象的Proxy对象而不是OrderRequest的真实实例,我错过了什么?似乎Doctrine2喜欢延迟加载,我似乎无法从它的屁股上取下它并为我取物。

更新: 我正在尝试使用以下代码在Twig模板中显示信息:

$order = $this->getDoctrine()
    ->getRepository('OrderRequestBundle:OrderRequest')
    ->getOrder($id);

return $this->render('OrderRequestBundle:Admin:view.html.twig', array('order' => $order));

其中Twig调用有关'order'变量的信息:

{{ order.quantity }}

...但我最终得到了这个错误:

Item "quantity" for "Array" does not exist in "OrderRequestBundle:Admin:view.html.twig" at line 5

2 个答案:

答案 0 :(得分:8)

更新

鉴于您的编辑,问题根本不是代理对象,而是您使用$ query对象的方式。

$query->getResult()将返回一系列结果。在这样的实例中,您将结果集限制为最多1行,它将返回一个包含一个条目的数组,但仍然是一个数组。当我尝试使用访问器方法时,Twig会对此产生窒息。

您要做的是使用$query->getSingleResult()代替。请注意,如果查询返回多行,则Doctrine将抛出一个非唯一结果异常,因此如果查询可能返回多个结果,则需要确保将其与setMaxResults(1)一起使用。 / p>

END UPDATE

来自reference proxies的文档:

  

这里$ item实际上是代理类的一个实例   为Item类生成但您的代码不需要关心。在   事实上它不应该关心。代理对象应该是透明的   代码。

强调他们的。代理应该对您的代码透明,并且存在以尽可能提高性能;但是,如果您迫切需要急切加载部分查询,则可以在实体配置文件中设置获取模式,或者查看文档的this section

$query = $em->createQuery("SELECT u FROM MyProject\User u");
$query->setFetchMode("MyProject\User", "address", "EAGER");
$query->execute();

答案 1 :(得分:1)

Doctrine2 始终从存储库查询返回代理对象。这些扩展您的实体类,并且出于所有意图和目的,都是相同的。

代理只是让您的实体支持延迟加载相关实体(以及其他内容)。

请参阅http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html?highlight=proxy#entity-object-graph-traversal