Details
Description
Currently, EntityManager#getReference can be used to retrieve cheap references to "persistent" objects without actually loading them. The returned proxies only initialize themselves automatically when one of their methods is invoked. This can lead to unnecessary/unwanted initialization in cases of bidirectional associations where the "association management methods" (setFoo) properly set the other side of the association. Example (one-one, User-Address, User owning side):
class User {
private $address;
public function setAddress(Address $address) {
if ($address !== $this->address) {
$this->address = $address;
$address->setUser($this);
}
}
}
class Address {
private $user;
public function setUser(User $user) {
if ($user !== $this->user) {
$this->user = $user;
$user->setAddress($this);
}
}
}
Now, assuming the following code that makes use of getReference to associate a user to an address but actually wants to avoid loading the address.
// assuming $user is already loaded and now we want to associate it to an existing address // but without actually loading the address $addressId = 42; // from request, $_POST/$_GET/... $address = $em->getReference('Address', $addressId); $user->setAddress($address); // calls $address->setUser which initializes the proxy! $em->flush();
A possible solution could be to allow obtaining single references to partial objects through the EntityManager. Partial objects can already be fetched through querying with the Query::HINT_FORCE_PARTIAL_LOAD query hint so the possibility to get a single partial object by ID seems to make sense.
A proposed method name is: getPartialReference($className, $id). It would return a managed (partial) instance of $className where only the identifier is populated and that will not initialize itself (hence "partial"). In the example above, usage of a partial reference object would avoid the extra initialization.
Sounds good to me, the method name is also very clear about that the retrieved object is partial, the only negative is that its really the only use-case for this method.