对已登录用户执行多个查询。部分加载不';不行。信条Symfony2
在我的Symfony2项目中,使用Doctrine2,我得到了一个用户类,它扩展了FOSUserBundle的用户类,该类具有许多关联,如地址、图像、命令等对已登录用户执行多个查询。部分加载不';不行。信条Symfony2,symfony,doctrine-orm,associations,lazy-loading,fosuserbundle,Symfony,Doctrine Orm,Associations,Lazy Loading,Fosuserbundle,在我的Symfony2项目中,使用Doctrine2,我得到了一个用户类,它扩展了FOSUserBundle的用户类,该类具有许多关联,如地址、图像、命令等 class User extends BaseUser{ /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") * @Expose */ protected $id; /** * * @ORM\OneToMa
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\u FORCE\u PARTIAL\u 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)代码>返回:{id:4,用户名:“coy”,电子邮件:“n****@gmail.com”}
结果:
- 2查询
- 没有任何关联的用户对象
未在登录用户上工作。。。
但是登录用户上的相同请求$user=$em->getRepository('ANGCustomerBundle:user')->testGetUser(3)代码>返回
{“id”:3,“用户名”:“bolz”,“电子邮件”:“h******@gmail.com”,“图像”:[{“id”:15,“url”:“png”},{“id”:20,“url”:“jpeg”}],“命令”:[{“id”:1,“创建日期”:“2016-03-25T15:52:40+0100”
结果:
- 128个查询
- 整个用户对象及其所有关联。我们可以看到,我们有用户的命令,但我们也有所有命令的关联实体,等等
看起来提示\u FORCE\u PARTIAL\u 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个查询
我已经被困在这里一个星期了,真的不明白这里发生了什么
我真的很感谢你阅读这篇长文章,希望有人能在这方面帮助我
非常感谢,Bastien。问题在于JMSSerializerBundle,它使用\JMS\Serializer\EventDispatcher\Subscriber\doctrineProxy订阅者
,其中调用了$object->\uu load();
,触发延迟加载
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();
}
看看这里,人们有同样的问题,并设法使其工作
希望能有所帮助。问题在于JMSSerializerBundle,它使用\JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber
调用$object->\uu load();
,触发延迟加载
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();
}
看看这里,人们有同样的问题,并设法使其工作
希望有帮助。你能用$em->getRepository('ANGCustomerBundle:User')->find(4)
当“find”函数加载每个关联时,它会返回整个用户对象。但我只需要“基本”用户对象,不需要关联实体。更具体地说,这里我得到User.username、User.email、User.id(我想要的)还有user.command.*,user.avatar.*,user.address.*,user.command.product.*,user.command.product.image.*等等…实际上所有关联实体,这就是我想要的avoid@Expose是JMSBundle的一部分,它用于选择发送或不发送到前端的属性,因为我的应用程序是RESTAPI它会在请求完成后进行操作,然后过滤结果Where/如何测试返回的结果?能否使用$em->getRepository('ANGCustomerBundle:User')->find(4)进行测试
当“查找”函数加载每个关联时,它会返回整个用户对象。但我只需要“基本”用户对象,而不需要关联实体。更具体地说,这里我得到User.username、User.email、User.id(我想要的)还有user.command.*,user.avatar.*,user.address.*,user.command.product.*,user.command.product.image.*等等…实际上所有关联实体,这就是我想要的avoid@Expose是JMSBundle的一部分,它用于选择发送或不发送到前端的属性,因为我的应用程序是RESTAPI它会在请求完成后进行操作,然后过滤结果Where/如何测试返回的结果?我目前无法用我的覆盖ProxySubscriber,它不起作用我不知道为什么,所以我直接对$object->\uu load();
行进行了注释。现在我得到了31个查询(130个没有注释)用户对象似乎加载了“2个深度级别”的关联实体。我的意思是,我有User.commands,User.commands[I].producer,但在producer中我只有id,而在不注释行的情况下,我还可以访问User.commands[I].producer.avatar,例如,甚至可以访问User.commands[I].producer.products[j].categorie等…因此,这似乎是50%的工作^^我想我开始更好地理解了^看起来我得到了所有的OneToOne、OneToMany和ManyToMany关系,但没有得到ManyToOne。因此,例如,在我的响应对象中,我得到了user.commands(OneToMany)、user.commands.command\u包(再次是OneToMany),但我没有user.commands.producer(只有id),因为它是多通的。我不确定它为什么会这样工作,但这似乎是一种逻辑行为。我将尝试看看是否可以避免那些1到1 1 to*&*to*关系,但仍有一些我不明白的地方。如果我运行我的请求“findAlls”(我在问题中链接的最后一个),仍然使用修改过的ProxyScriber,我得到了32个查询:1个用于选择所有用户(没有任何关联),31个用于登录用户。因此,我得到了所有用户的id、用户名、电子邮件,但对于登录用户,仍然有我描述的那种“2级深度对象”