Grzegorz Krauze
Grzegorz Krauze

Reputation: 1148

Doctrine2 - proxy object among regular objects in getResult

In my Symfony2 controller, I have two queries:
like in this example:

$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();

Effect that I receive in collection $objects is collection of SomeBundle:SomeEntity objects except for the one that I received to variable $object for which I receive Proxy object.

If I output $objects collection and for each element I want to print output that includes fields: name, field1, field2, I receive null for field2 for this object. In fact if I get this $object in any other controller launched with this one together, the field2 is also null on each reference to the object.

For example, if I want to display each object as:

name field1 field2

I get following array for $objects:

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

where the third row is the $object.
If I get field2 in the first query it is also visible on getResult of the second one. But that makes me control all fields received for any Entity object in whole Request.

  1. What could I made wrong?
  2. How can I avoid that effect? I still want to work with objects not with multidimensional arrays (as for HYDRATE_ARRAY)
  3. Is there a way to force doctrine to result always with entity objects not with proxies objects?

Thank you in advance.

Upvotes: 4

Views: 756

Answers (1)

Jory Geerts
Jory Geerts

Reputation: 1977

This happens because Doctrine keeps an internal reference to each entity it returns. When you request an entity you've requested before, it will re-use the previous object. The reason for this is that having two different copies of the same entity would create conflicts if you try to manipulate both of them. For more details, see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork.html#how-doctrine-keeps-track-of-objects

The one solution is to detach the entity you got first (using either $em->detach($object) or $em->clear()) before executing the second query. Be aware, any changes you've made that have not been flushed yet will be gone.

Another option is to either refresh the entity using $em->refresh($object) (this will cause it to be fully loaded) or tell Doctrine it needs to refresh all entities for the second query:

$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();

This will make Doctrine refresh all the entities it finds for this second query.

Upvotes: 2

Related Questions