I am loading a list of many entities.
These entities have a one-to-many association to other entities.
I want to load all these other entities in one single SQL query (instead of one query for every entity in the first list).
As discribed in the doctrine2 documentation: http://www.doctrine-project.org/docs/orm/2.1/en/reference/dql-doctrine-query-language.html#temporarily-change-fetch-mode-in-dql this should be possible with "EAGER" loading.
but it does not work as described.
my code:
class User{
/**
* @ORM\OneToMany(targetEntity="Address", mappedBy="user", indexBy="id", fetch="EAGER")
*/
protected $addresses;
public function __construct(){
$this->addresses = new ArrayCollection();
}
}
class Address{
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="addresses")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="UserId", referencedColumnName="id")
* })
*/
private $user;
}
class UserRepository{
public function findUsersWithAddresses(){
return $this->getEntityManager()
->createQuery('SELECT u FROM MyBundle:User u ORDER BY u.name ASC')
->setFetchMode('MyBundle\Entity\User', 'addresses', \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER)
->setMaxResults(10)
->getResult();
}
}
The method UserRepository::findUsersWithAddresses() executes 11 SQL Queries.
How can I tell Doctrine to use only one SQL Query to load the address entities?
I am using:
- symfony v2.0.9
- doctrine-common 2.1.4
- doctrine-dbal 2.1.5
- doctrine 2.1.5
I had exactly the same issues and updated my doctrine module in Zend Framework 2 to version 2.5 and now all is working fine. You can check my question here
According to your link:
It looks like the current version of Doctrine does not support eager loading on a one-to-many collection, unfortunately.
This page seems to confirm this supposition:
The
@OneToMany
annotation does not feature afetch
attribute, as opposed to@OneToOne
and@ManyToOne
.Update
I just noticed that you can actually eager fetch the related entities, using an explicit
LEFT JOIN
in DQL:Do use a
LEFT JOIN
, and not an innerJOIN
, or entities with an empty collection (User
without anyAddress
) would be omitted from the result set.Update (2017)
As pointed by GusDeCool and webDEVILopers in the comments, the
fetch
attribute is now supported on@OneToMany
. The above answer is now obsolete.The current version of doctrine doesn't support this.
There is a feature request about this in the doctrine2 issue tracker.
So I hope it will be implemented soon.