生成されたプロキシクラスの1つを見ると、__load()
と__clone()
関数の両方がをスローしていることがわかりますEntityNotFoundException
。
__load()
関数を「怠惰に」呼び出すと、関数が呼び出されますgetName()
。
class ObjectB extends \Foo\Entity\ObjectB implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
...
public function getName()
{
$this->__load();
return parent::getName();
}
...
}
基本的にいくつかのオプションがあります。最初のオプションはtry/catch
ブロックを使用することです。
try {
$name = $objectB->getName();
} catch (\Doctrine\ORM\EntityNotFoundException $e) {
$name = null;
}
または、__wakeup()
関数を実装しObjectB
、場合によってはこれを自分で処理する方法を確認することもできます(ただし、とにかく例外をスローする必要がある可能性が高くなります)。
最後に、野心的な場合は、Proxy
テンプレートを変更できます。\Doctrine\ORM\Proxy\ProxyFactory
テンプレートが含まれています。
/** Proxy class code template */
private static $_proxyClassTemplate =
'<?php
namespace <namespace>;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class <proxyClassName> extends \<className> implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
意図しない副作用があるかもしれませんがEntityNotFoundException
、__load()
と関数のスローを削除するだけで逃げることができるはずです。__clone()
Doctrineを定期的にアップグレードする予定がある場合は、この変更をパッチとして行うことも検討してください。