Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lazy loading with doctrine one to one mapping

Tags:

I am having a hard time finding the correct result for this.

I have one to one mapping. There are two tables:

/**
* @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;
}

Whenever I fetch entity one as below:

$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 immediately performs join to usersSettings entity which I dont want:

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 = ?

Other types of mapping like OneToMany and ManyToOne performs lazy loading but in case of one to one mapping, I could not configure to lazy load. How can I lazy load this relation? I am using doctrine 2.3 and Symfony 2.1

like image 908
sonam Avatar asked Jan 21 '13 02:01

sonam


People also ask

How lazy loading works in Hibernate?

Lazy loading in Hibernate means fetching and loading the data, only when it is needed, from a persistent storage like a database. Lazy loading improves the performance of data fetching and significantly reduces the memory footprint.

What is lazy loading in Symfony?

In Symfony 6.2, the VarExporter component will ship two new traits to help implement lazy-loading objects. As their names suggest, lazy-loading objects are initialized only when actually needed; typically when accessing one of their properties. They're used when an object is heavy to instantiate but is not always used.

What is fetch eager?

Eager fetching is the ability to efficiently load subclass data and related objects along with the base instances being queried.


2 Answers

Use hint HINT_FORCE_PARTIAL_LOAD to avoid lazy-loading.

...
$qb->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
like image 147
Łukasz Feller Avatar answered Oct 21 '22 22:10

Łukasz Feller


Inverse sides of one-to-one associations can not be lazy.

Explanation:

This is expected behavior. There is no foreign key on the inverse side, hence it is impossible to decide whether to proxy it or not. We must query for the associated object or join it. Note that this only affects inverse sides of single-valued associations, that is, really only the inverse side of bidirectional one-to-one associations.

Why we cannot create proxy without FK?

It is pretty simple, in a one-to-many association where the one-side is the inverse side, it holds a collection. The collection may be empty or not but there can always be a collection so it easy and correct to always put a proxy collection there.

If you have a single-valued side that is the inverse side, how can you decide whether to put a proxy object there or not? Without seeing the foreign key you have no way to distinguish between: There is no associated object (and thus putting a proxy object in place would by simply wrong) or there is one and of which type it is, if inheritance is involved (since putting a proxy of the wrong type in is also wrong).

See discusion on https://github.com/doctrine/orm/issues/4389

like image 35
jparedes Avatar answered Oct 21 '22 21:10

jparedes