Symfony2
Doctrine2

`id`だけほしいのに`Entity`が必要な場合は、`EntityManager#getPartialReference`を使う

More than 1 year has passed since last update.

はじめに

$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は、それなりに使いどころありそうです。
まずは、テストコードなどから、少しずつ使い始めて実績積んでいきたいですね。
ではでは。

参考URL