对已登录用户执行多个查询。部分加载不';不行。信条Symfony2

对已登录用户执行多个查询。部分加载不';不行。信条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

在我的Symfony2项目中,使用Doctrine2,我得到了一个用户类,它扩展了FOSUserBundle的用户类,该类具有许多关联,如地址、图像、命令等

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级深度对象”