延迟加载与doctrine一对一映射

时间:2013-01-21 02:52:52

标签: 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;
}

每当我按如下方式获取实体一时:

$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();

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

3 个答案:

答案 0 :(得分:15)

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

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

答案 1 :(得分:0)

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

说明:

  

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

     

为什么没有FK无法创建代理?

     

这很简单,在一对多关联中,一侧是反面,它保存一个集合。集合可以为空,也可以不为空,但是总可以有一个集合,因此始终在其中放置代理集合很容易且正确。

     

如果您有一个单值方面,即相反方面,您如何决定是否在其中放置代理对象?如果没有看到外键,就无法区分:没有关联的对象(因此将代理对象放在适当的位置会很容易出错),或者如果涉及到继承,则存在一个对象,并且是哪个类型(因为放置继承)输入错误的代理也是错误的。

查看有关https://github.com/doctrine/orm/issues/4389的讨论

答案 2 :(得分:-3)

您可以在注释中使用fetch="EXTRA_LAZY"启用extra lazy个关联加载。

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