web-dev-qa-db-ja.com

getReference()of doctrine Entity Manager

状況:

Doctrine2 Entity Managerの getReference() 関数を使用したい。ただし、データベースから削除されたオブジェクトを要求する状況で、同じオブジェクトを複数回要求するとプロキシを取得します。

例:

_//A random article object...that has been deleted from the database
$articleClass = 'Acme\ArticleBundle\Entity\Article';
$articleIdentifiers = array('id'=>1);
$i = 0;

//We ask for its reference twice
do{
    try {
        echo "a";
        $subject = $this->em->getReference(
            $subjectClass,
            $subjectIdentifiers
        );
       //call this object now
       var_dump($subject);

    } catch (\Exception $e) {
        echo "b";
    }
    $i++;
} while ($i <2);
_

出力:

_a
b
a
object(Proxies\__CG__\Acme\ArticleBundle\Entity\Article)
_

データベースにも存在しないオブジェクトのプロキシを取得するにはどうすればよいですか?コメント この行 の場合、entityManagerはオブジェクトを管理せず、出力ababを取得します。これは、プロキシオブジェクトを取得したくないので、私にとっては理にかなっています。データベースに存在しません。参考までに、返されるプロキシオブジェクトにはすべてのプロパティnullがあります。したがって、データベースに存在しないオブジェクトのプロキシを取得します。したがって、このオブジェクトを要求すると、「エンティティが見つかりません」という例外が発生します。

挑戦

誰かがこれを理解できますか? getReference()に依存して、このオブジェクトが実際にデータベースに存在するかどうかを通知する方法はありますか?

10
Mick

getReference()に参照されたオブジェクトの存在についてデータベースをチェックさせる方法はありません。

実際には、これがgetReference()とそれによって返されるプロキシのすべてです。データベースにアクセスせずにプレースホルダーオブジェクト(プロキシ)を作成します。そして、それを明示的に行いたいと思うことはめったにありません。通常、Doctrineは、エンティティをハイドレイティングして、外部キー値に基づいて関連エンティティの遅延読み込みプレースホルダーを作成するときに、これを内部的に行います。

エンティティマネージャでfind()を呼び出してみませんか? IDで検索する限り、EMがDBに同じオブジェクトを複数回クエリしないことをご存知ですか? Doctrineは、作業ユニット内のすでにハイドレイトされたオブジェクトを追跡し、後続のfind()呼び出しで既存のオブジェクトへの参照を返します。

20
literal

getReferenceを使用してオブジェクトを取得した後、getNameなどのメソッドを呼び出すと、DoctrineはDBからエンティティをフェッチします。プロパティ(getName)を見つける他の方法はありません。


あなたの挑戦に関して:

EntityManager->contains($entity)は、doctrineのエンティティがエンティティマネージャにあるかどうかを確認するための推奨される方法です。

2
Andrew Atkinson

参照を取得し、データベースに含まれているかどうかを確認する必要があります。

$classChild = $this->doctrine->getReference($classReference, $id);                                
if (!$this->doctrine->contains($classChild)) {
    throw new \Exception("Invalid Reference");
}

$ this-> doctrineはEntityManagerです。