对登录用户的许多查询。部分加载不起作用。学说 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"}
结果:
- 2 个查询
- 没有任何关联的用户对象
登录用户不工作...
但对登录用户的相同请求 $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", .....
结果:
- 128 个查询
- 整个用户对象,以及他的所有关联。我们可以看到我们有用户的命令,但我们也有所有命令的关联实体等等...
看起来 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 人们遇到了同样的问题并设法解决了这个问题。
希望对您有所帮助。
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"}
结果:
- 2 个查询
- 没有任何关联的用户对象
登录用户不工作...
但对登录用户的相同请求 $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", .....
结果:
- 128 个查询
- 整个用户对象,以及他的所有关联。我们可以看到我们有用户的命令,但我们也有所有命令的关联实体等等...
看起来 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 人们遇到了同样的问题并设法解决了这个问题。
希望对您有所帮助。