How to get objects without matching associations in Doctrine 2

If you have a set of mapped objects in Doctrine, sometimes you may need to extract these objects if their mapped associations are not retrieved and will not slow down the query.

For example, I have a set of objects that are interconnected in a chain of related database tables. All of them are OnetoMany associations and act as a hierarchy of prices in matrices on product pages. They can be represented as follows:

SitePage->SiteMatrix->SiteItems->SiteItemPrices. 

The corresponding mapping works fine, and when I use the findBy method to get the root SitePage, it contains arrays that represent the displayed objects in the chain. In other words, the SitePage object contains all matrices containing all elements containing all prices. So far so good.

My problem is that every time I get a list of pages on my site, the doctrine goes through the whole association map tree and returns me with all the necessary database, which is very slow. Someday I just want to get the SitePage object by ID and not contain all the associations associated.

I looked at the lazy and excess lazy loading of associations, but they only affect certain functions, and do not find By, etc. The official documentation is far from useful: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html

Other similar questions about stack overflows remained unanswered: Overhead for adapting the Doctrine 2 association?

Is there an easy way to get an object without matching mappings? The easiest way that I see at the moment is to create two objects for each database table: one with association associations and one without use in separate situations where they are needed. It seems strange to me that you cannot just get an entity and indicate whether you want to bind it to other objects or get it yourself.

Thanks for any info on this.

+5
source share
1 answer

JMSSerializer exclusion strategies can help you.

First, exclude all default properties:

 // ... use JMS\Serializer\Annotation as JMS; /** * @ORM\Entity * @JMS\ExclusionPolicy("all") */ class Foo 

Then choose to exclude or publish your properties:

 /** * @ORM\Column(type="string") * @JMS\Expose */ protected $name; 

In addition, for your associations, you can use MaxDepth to limit the related records of your results. Example:

 // Entity /** @MaxDepth(1) */ private $selfAssociatedEntries; // Controller use JMS\Serializer\SerializationContext; $serializer->serialize($data, 'json', SerializationContext::create()->enableMaxDepthChecks()); 

Similarly, your object will contain a series of $selfAssociatedEntries , but $selfAssociatedEntries does not have the $selfAssociationEntries .
Serialization is limited to the first parent.

Groups is a powerful feature that allows you to set properties for some actions and exclude them for another:

 /** * @ORM\Column(type="string", length=255, nullable=true, unique=false) * @JMS\Groups({"default"}) // Set the group to expose the property */ protected $name; 

In your controller, set the group used for serialization:

 // Property 'name' is exposed $serializer->serialize($data, 'json', SerializationContext::create()->setGroups(array('default'))); 

See the "Exclusion Strategies" in the documentation for more information.

+2
source

Source: https://habr.com/ru/post/1240696/


All Articles