enter image description hereIn my Symfony2 project, using Doctrine2, I got a User class extending the FOSUserBundle's User class, which has a lot of associations, as an adress, images,commands, etc..
class User extends BaseUser{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Expose
*/
protected $id;
/**
*
* @ORM\OneToMany(targetEntity="ANG\CommandBundle\Entity\Command", cascade={"persist", "remove"}, mappedBy="customer")
*@Expose
*
*/
private $commands;
/**
*
* @ORM\OneToOne(targetEntity="ANG\FileBundle\Entity\Image", cascade={"remove"})
* @ORM\JoinColumn(onDelete="SET NULL")
* @Assert\Valid()
* @MaxDepth(1)
* @Expose
*/
private $banner;
/**
*
* @ORM\OneToOne(targetEntity="ANG\FileBundle\Entity\Image", cascade={"remove"})
* @ORM\JoinColumn(onDelete="SET NULL")
* @Assert\Valid()
* @MaxDepth(2)
* @Expose
*/
private $avatar;
/**
*
* @ORM\OneToMany(targetEntity="ANG\MainBundle\Entity\Address", cascade={"persist", "remove"}, mappedBy="customer")
*@MaxDepth(1)
*@Expose
*/
private $address;
/**
*
* @ORM\OneToMany(targetEntity="ANG\MainBundle\Entity\Invitation" , mappedBy="customerSender", cascade={"persist", "remove"})
*
*/
protected $invitationsSend;
...
I realised that when I do $this->getUser()
in a controller, the doctrine lazy loading executes 128 queries... (which is far too much to be acceptable)
So I created my own function in the UserRepository, using setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
to avoid the lazy loading.
public function testGetUser($id){
$em=$this->getEntityManager();
$qb=$em->createQueryBuilder()
->select('cs')
->from('ANGCustomerBundle:User', 'cs')
->where('cs.id = :id')
->setParameter('id', $id);
return $qb->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)->getOneOrNullResult();
}
My problem : That function does not work for the logged in user.
Example:
I'm logged in with the User having ID = 3
Working on all users except me
For every ID != 3, the abose request is working.
$user = $em->getRepository('ANGCustomerBundle:User')->testGetUser(4);
returns: {id: 4, username: "coy", email: "n****@gmail.com"}
Result:
- 2 queries
- User object without any associations
Not working on the logged in user...
But the same request on the logged in user $user = $em->getRepository('ANGCustomerBundle:User')->testGetUser(3);
returns
{"id":3,"username":"bolz","email":"h******@gmail.com","images":[{"id":15,"url":"png"},{"id":20,"url":"jpeg"}],"commands":[{"id":1,"date_creation":"2016-03-25T15:52:40+0100", .....
Result:
- 128 queries
- The entire User object, with all his associations. We can see that we have the user's command, but we also have all the command's associate entities and so on ...
It looks like the HINT_FORCE_PARTIAL_LOAD doesn't apply on the logged in user .
Just to conclude, this problem is also present if I request on all the users together.
public function findALLs(){
$em=$this->getEntityManager()
->createQueryBuilder()
->select('cs')
->from('ANGCustomerBundle:User', 'cs')
->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)->getResult();
}
For all users except the logged on : username, email, id
But like for the 1st function, we have the entire structure for the logged in user, doing once again, 128queries...
I've been stuck for a week now on this and really don't understand what's happening here.
I really thank you for reading this long post, and hope someone could help me on this one.
With much thanks, Bastien.