延迟加载与doctrine一对一映射

son*_*nam 17 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="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;
}
Run Code Online (Sandbox Code Playgroud)

每当我获取实体一如下:

$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();
Run Code Online (Sandbox Code Playgroud)

Doctrine立即执行到我不想要的usersSettings实体的连接:

SELECT t0.id AS id1,t0.username AS username2,t0.email AS email3,t0.password AS password4,t29.id AS id30,t29.is_notify_by_email AS is_notify_by_email31,t29.user_id AS user_id32 FROM users t0 LEFT JOIN users_settings t29 ON t29.user_id = t0.id WHERE t0.id =?

其他类型的映射类似于OneToManyManyToOne执行延迟加载但是在一对一映射的情况下,我无法配置为延迟加载.我怎么能懒得加载这种关系?我正在使用doctrine 2.3和Symfony 2.1

Łuk*_*ler 16

使用提示HINT_FORCE_PARTIAL_LOAD以避免延迟加载.

...
$qb->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
Run Code Online (Sandbox Code Playgroud)

  • 这当然暴露了另一个问题 - 如果你只想获得未加入的实体的键值(例如id),它将引发异常. (3认同)

小智 7

一对一关联的反面不能偷懒。

解释:

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

为什么我们不能在没有 FK 的情况下创建代理?

这很简单,在一对多关联中,其中一侧是相反侧,它包含一个集合。集合可能是空的也可能不是,但总有一个集合,所以总是在那里放置一个代理集合很容易和正确。

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

请参阅https://github.com/doctrine/orm/issues/4389 上的讨论


lif*_*ifo -3

您可以在注释中使用关联的额外延迟加载。fetch="EXTRA_LAZY"

* @ORM\OneToOne(targetEntity="Users", inversedBy="userSetting", fetch="EXTRA_LAZY")
Run Code Online (Sandbox Code Playgroud)

  • 添加 extra_lazy 后它仍然会加入表。我以前也尝试过,但没成功 (5认同)
  • 我遇到了完全相同的问题,即 OneToOne 关联对每个关联实体执行多个单独的查询(即使该实体中没有属性被访问)。添加 fetch="EXTRA_LAZY" 也没有解决我的问题(文档解释了原因)。[查看有关有效方法的更多详细信息](http://stackoverflow.com/a/27112833/3334390)。 (5认同)