Im using Doctrine 2 ORM in my Zend project and need to serialize my Entities to JSON in several cases.
ATM i use the Querybuilder and join all tables i need. But my serializer causes doctrine to lazy load every associated Entity which results in pretty huge data amounts and provokes recursion.
Now im looking for a way to totally disable Doctrines lazy loading behavior.
My way to select data would be the following:
$qb= $this->_em->createQueryBuilder()
->from("\Project\Entity\Personappointment", 'pa')
->select('pa', 't', 'c', 'a', 'aps', 'apt', 'p')
->leftjoin('pa.table', 't')
->leftjoin('pa.company', 'c')
->leftjoin('pa.appointment', 'a')
->leftjoin('a.appointmentstatus', 'aps')
->leftjoin('a.appointmenttype', 'apt')
->leftjoin('a.person','p')
I would like my resultset to only contain the selected tables and associations.
Any help would be greatly appreciated.
After having looked for the answer in Doctrine, my team figured out that the JMS Serializer was the "problem". It triggered the use of Doctrine Proxies automatically. We wrote a Patch for JMS Serializer to avoid the Lazy Loading.
We implemented our own DoctrineProxyHandler which just doesn't trigger Doctrines lazyloading mechanism and registered it within our SerializationHandlers Array.
Now i can simply select my table, join the associations i need - and my JSON will contain just the data i selected instead of infinite depth associations and recursions :)
JSON will just contain
When using Doctrine's query builder, you can't disable lazy loading of linked model classes. If you want to bypass such behavior, you better have to request data with Doctrine's DBAL.
Don't use
\Doctrine\ORM\QueryBuilder
but\Doctrine\DBAL\Query\QueryBuilder
.Case you want pragmatically use your or default subscriber,
@DavidLin answer:
you can copy the class from JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber to Your\Bundle\Event\DoctrineProxySubscriber and comment out the $object->__load(); line
And initialize the serialize like this:
This may very well be called an ugly crutch, but you could just select() the data that you really need, then hydrate the result to an array using the getArrayResult() method of the Query object...
In the latest version of JMSSerializer, the place you should look at is
instead of
To override the default lazy load behavior, one should define his own event subscriber.
In your
app/config.yml
add this:you can copy the class from JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber to Your\Bundle\Event\DoctrineProxySubscriber and comment out the $object->__load(); line