Avoid Doctrine to return all entities

2020-04-21 01:17发布

问题:

Using Symfony2 / doctrine2, while we use the find() function to get a specific object based on the entity selected if there are relations (like OneToMany), Doctrine return all other object.

For example :

$em = $this->get(
         'doctrine.orm.entity_manager', 
          $request->getSession()->get('entity_manager')
);
$product = $em->getRepository('MyBundle:Product')->find($id);

The result on $product will be the Product object + other linked objects like (Store, Category, ...etc.)

How can we control doctrine to determinate which object we need to be returned.

I can use Querybuilder, but i am looking if there are any function all determinate.

回答1:

Doctrine return all other object

This is not how it works, at least by default.

Doctrine uses what is called lazy loading.
From the official documentation, you have the following example:

<?php
/** @Entity */
class Article
{
    /** @Id @Column(type="integer") @GeneratedValue */
    private $id;

    /** @Column(type="string") */
    private $headline;

    /** @ManyToOne(targetEntity="User") */
    private $author;

    /** @OneToMany(targetEntity="Comment", mappedBy="article") */
    private $comments;

    public function __construct {
        $this->comments = new ArrayCollection();
    }

    public function getAuthor() { return $this->author; }
    public function getComments() { return $this->comments; }
}

$article = $em->find('Article', 1);

And the following explanation:

Instead of passing you back a real Author instance and a collection of comments Doctrine will create proxy instances for you. Only if you access these proxies for the first time they will go through the EntityManager and load their state from the database.

Reference: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#entity-object-graph-traversal

More information about the topic: http://www.doctrine-project.org/blog/doctrine-lazy-loading.html



回答2:

You can configure extra lazy associations to avoid loading of relations in general.

/**
 * @ManyToMany(targetEntity="CmsUser", mappedBy="groups", fetch="EXTRA_LAZY")
 */
protected $property;