对登录用户的许多查询。部分加载不起作用。学说 Symfony2

To many queries for logged in user. Partial loading doesn't work. Doctrine Symfony2

enter image description here在我的 Symfony2 项目中,使用 Doctrine2,我得到了一个用户 class 扩展了 FOSUserBundle 的用户 class,它有很多关联,如地址、图像、命令等。

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;

...

我意识到,当我在控制器中执行 $this->getUser() 时,延迟加载原则会执行 128 次查询...(这太多了,无法接受)

所以我在 UserRepository 中创建了自己的函数,使用 setHint(Query::HINT_FORCE_PARTIAL_LOAD, true) 来避免延迟加载。

    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();
}

我的问题:该功能对登录用户不起作用。

示例:

我使用 ID = 3 的用户登录

正在处理除我以外的所有用户

对于每个 ID != 3,上面的请求都有效。

$user = $em->getRepository('ANGCustomerBundle:User')->testGetUser(4); returns: {id: 4, 用户名: "coy", 邮箱: "n****@gmail.com"}

结果:

登录用户不工作...

但对登录用户的相同请求 $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", .....

结果:

看起来 HINT_FORCE_PARTIAL_LOAD 不适用于登录用户 .

总结一下,如果我对所有用户一起请求,也会出现这个问题。

public function findALLs(){
    $em=$this->getEntityManager()
        ->createQueryBuilder()
        ->select('cs')
        ->from('ANGCustomerBundle:User', 'cs')
        ->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)->getResult();
}

除了已登录的所有用户:用户名、电子邮件、ID

但是就像第一个函数一样,我们拥有登录用户的整个结构,再次执行 128 次查询...

我已经被困了一个星期了,真的不明白这里发生了什么。

非常感谢您阅读这么长的内容post,希望有人能在这方面帮助我。

非常感谢,Bastien。

问题出在 JMSSerializerBundle 上,它使用 \JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber,其中调用了触发延迟加载的 $object->__load();

看到这个 question 人们遇到了同样的问题并设法解决了这个问题。

希望对您有所帮助。