Doctrine2 - getResult

时间:2016-11-19 10:02:53

标签: symfony doctrine-orm

在我的Symfony2控制器中,我有两个问题:
就像在这个例子中一样:

$object = $this->getDoctrine()->getManager()
           ->createQuery('SELECT PARTIAL o.{id,name,field1} 
                          FROM SomeBundle:SomeEntity o  
                          WHERE o.id = :objectId')
                    ->setParameter('objectId', $objectId)
                    ->getResult();



$objects = $this->getDoctrine()->getManager()
           ->createQuery('SELECT PARTIAL o.{id,name,field1, field2} 
                          FROM SomeBundle:SomeEntity o ')
                    ->getResult();

我在集合$objects中收到的效果是SomeBundle:SomeEntity个对象的集合,除了我收到的变量$object,我收到了它的代理对象。

如果我输出$objects集合,并且对于每个元素我想要打印包含字段的输出:name,field1,field2,我为此对象收到field2的null。实际上,如果我在使用这个控制器启动的任何其他控制器中获得此$object,则对于对象的每个引用,field2也为null。

例如,如果我想将每个对象显示为:

name field1 field2

我得到$objects的以下数组:

nameExample field1Example field2Example
nameExample field1Example field2Example
nameExample field1Example 
nameExample field1Example field2Example
nameExample field1Example field2Example

第三行是$object 如果我在第一个查询中获得field2,它也可以在第二个查询的getResult上看到。但这使我能够控制整个Request中任何Entity对象收到的所有字段。

  1. 我有什么不对的?
  2. 我该如何避免这种影响?我仍然希望使用不具有多维数组的对象(对于HYDRATE_ARRAY
  3. 是否有办法强制学说始终使用不具有代理对象的实体对象?
  4. 提前谢谢。

1 个答案:

答案 0 :(得分:2)

这是因为Doctrine保留了对它返回的每个实体的内部引用。当您请求之前请求的实体时,它将重新使用上一个对象。这样做的原因是,如果您尝试操纵它们,则拥有同一实体的两个不同副本会产生冲突。有关详细信息,请参阅http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork.html#how-doctrine-keeps-track-of-objects

一种解决方案是在执行第二个查询之前分离您首先获得的实体(使用$em->detach($object)$em->clear())。 请注意,您所做的任何尚未刷新的更改都将消失。

另一种选择是使用$em->refresh($object)刷新实体(这将导致它完全加载)或告诉Doctrine需要刷新第二个查询的所有实体:

$query = $this->getDoctrine()->getManager()->createQuery('SELECT PARTIAL o.{id,name,field1, field2} FROM SomeBundle:SomeEntity o ');
$query->setHint(Query::HINT_REFRESH, true);
$objects = $query->getResult();

这将使Doctrine刷新它为第二个查询找到的所有实体。