はじめに
$userId
から、Entity\User
がほしいケース。
副作用がないように、setId
は実装されていないから、UserRepository#find
などでEntity\User
全体を読み込みます。
ただ、必要なのはuserId
であって他のプロパティは不要という場合は、何だか処理が無駄になっている気がしてきます。
EntityManager#getPartialReference
そんなときは、EntityManager#getPartialReference
を使います。
// vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php
public function getPartialReference($entityName, $identifier)
{
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
// Check identity map first, if its already in there just return it.
if (($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) !== false) {
return ($entity instanceof $class->name) ? $entity : null;
}
if ( ! is_array($identifier)) {
$identifier = array($class->identifier[0] => $identifier);
}
$entity = $class->newInstance();
$class->setIdentifierValues($entity, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
$this->unitOfWork->markReadOnly($entity);
return $entity;
}
$class->setIdentifierValues
からは、下記のコードが呼び出されます。
さらに、深く追っていけば、分かりますが、アクセスできない$id
プロパティにReflection
で値をセットします。
// vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
public function setIdentifierValues($entity, array $id)
{
foreach ($id as $idField => $idValue) {
$this->reflFields[$idField]->setValue($entity, $idValue);
}
}
おわりに
EntityManager#getPartialReference
は、それなりに使いどころありそうです。
まずは、テストコードなどから、少しずつ使い始めて実績積んでいきたいですね。
ではでは。