Symfony 一对一映射的延迟加载原则

Symfony 一对一映射的延迟加载原则,symfony,doctrine-orm,Symfony,Doctrine Orm,我很难找到正确的结果 我有一对一的映射。有两个表格: /** * @ORM\Table(name="users") * @ORM\Entity */ class Users { /** * @ORM\OneToOne(targetEntity="UsersSettings", mappedBy="user",cascade={"persist"}) */ private $userSetting; //getters and setters } /** *

我很难找到正确的结果

我有一对一的映射。有两个表格:

/**
* @ORM\Table(name="users")
* @ORM\Entity
*/
class Users {

   /**
    * @ORM\OneToOne(targetEntity="UsersSettings", mappedBy="user",cascade={"persist"})
   */
   private $userSetting;

   //getters and setters
}

/**
* @ORM\Table(name="notifications_settings")
* @ORM\Entity
*/
class UsersSettings {

   /**
   * @var Users
   *
   * @ORM\OneToOne(targetEntity="Users", inversedBy="userSetting")
   * @ORM\JoinColumns({
   *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
   * })
   */
   private $user;
}
每当我获取实体1时,如下所示:

$q = $this
            ->createQueryBuilder('u')
            ->select('u, r')
            ->leftJoin('u.roles', 'r')
            ->where('u.username = :username OR u.email = :email')
            ->setParameter('username', $username)
            ->setParameter('email', $username)
            ->getQuery();
条令立即执行加入用户设置实体,我不希望:

选择t0.id作为id1,t0.username作为username2,t0.email作为email3,t0.password作为password4,t29.id作为id30,t29.is通过电子邮件通知作为 是否通过电子邮件31通知?t29。用户id为用户id 32,从用户t0向左加入 用户设置t29上的t29。用户id=t0.id,其中t0.id=

其他类型的映射,如
OneToMany
manytone
执行延迟加载,但在一对一映射的情况下,我无法配置为延迟加载。如何延迟加载此关系?我使用的是doctrine 2.3和Symfony 2.1,您可以在注释中使用
fetch=“EXTRA_LAZY”
来启用关联加载

* @ORM\OneToOne(targetEntity="Users", inversedBy="userSetting", fetch="EXTRA_LAZY")

使用提示强制部分加载以避免延迟加载

...
$qb->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);

一对一关联的反向边不能是懒惰的

说明:

这是预期的行为。相反侧没有外键,因此无法决定是否代理它。我们必须查询关联的对象或加入它。请注意,这只影响单值关联的反向边,也就是说,实际上只影响双向一对一关联的反向边

为什么我们不能创建没有FK的代理

这很简单,在一对多关联中,一边是反面,它保存一个集合。集合可以是空的,也可以不是空的,但总可以有一个集合,因此总是将代理集合放在那里很容易而且正确

如果有一个单值的边是相反的边,那么如何决定是否将代理对象放在那里?如果没有看到外键,您就无法区分:没有关联的对象(因此,如果涉及继承,那么放置代理对象将完全错误),或者存在一个以及它是哪种类型的对象(因为放置错误类型的代理也是错误的)


请参见

的讨论,在添加额外的\u之后,它仍然会加入表。我以前也试过,但是你的服务器使用APC吗?更新注释后,请确保清除apc缓存(如果必须,请重新启动apache)。我对某些条令注释有一些问题,除非我重新启动apache,否则这些注释不会生效。我以前启用过APC,但在开发过程中遇到了麻烦,因此APC不能启用,另一个选项是使用DQL并创建如下查询:
从TestBundle:users u WHERE…
中选择u,这样您就不会获得连接。我遇到了与OneToOne关联对每个关联实体执行多个单独查询完全相同的问题(即使该实体中没有访问任何属性)。添加fetch=“EXTRA_LAZY”也不能解决我的问题(文档解释了原因)。这当然暴露了另一个问题——如果您只想获取未加入的实体的键值(例如id),它将引发异常。