doctrine、loggable (DoctrineExtension)、リスナーに関連する本当に奇妙なケースがあります。
ここで私が抱えている状況を説明します。以下は、問題に関連していると思われるすべてのコードです。
契約書が特定のテンプレート バージョンに基づいている 2 つのエンティティ (契約書とテンプレート) があります。テンプレート エンティティには DoctrineExtension Loggable アノテーションがあります。したがって、LogEntryRepository->revert() メソッドを使用して、契約テンプレートを特定のバージョンに戻すことができます。(これを行うために postLoad リスナーを使用しているため、契約書が取得されるたびに、その契約書の適切なテンプレート バージョンが読み込まれます)。
ParamConverter アノテーションを使用して契約書を取得するコントローラー アクションを取得すると、すべてが正常に機能し、適切なテンプレートで契約書が取得されます。クエリ ビルダーを使用して、コントローラー アクションの最初の行でまったく同じ合意を取得しようとすると、次の例外が発生します。
Notice: Trying to get property of non-object in /home/administrator{dir}/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php line 481
どんな助けでも大歓迎です。ありがとう。
問題に関連する部分をコピーするだけです:
エンティティ
/**
* Agreement
*
* @ORM\Table(name="agreement")
* @ORM\Entity
* @Gedmo\Loggable
*/
class Agreement
{
/**
* @var integer
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var integer
* @ORM\Column(name="template_version", type="bigint", nullable=false)
* @Gedmo\Versioned
*/
private $templateVersion;
/**
* @var \Template
* @ORM\ManyToOne(targetEntity="Template")
* @ORM\JoinColumn(name="template_id", referencedColumnName="id")
*/
private $template;
}
/*
* Template
*
* @ORM\Table(name="template")
* @ORM\Entity
* @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
* @Gedmo\Loggable
*/
class Template
{
/**
* @var integer
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
* @Gedmo\Versioned
*/
private $name;
}
ドクトリン加入者
*(services.yml)*
services:
ourdeal.listener.loggable:
class: App\Bundle\Listener\LoggableSubscriber
tags:
- { name: doctrine.event_subscriber }
class LoggableSubscriber implements EventSubscriber
{
public function getSubscribedEvents()
{
return array(
'prePersist',
'postLoad',
);
}
public function prePersist(LifecycleEventArgs $args)
*...Code omitted...*
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if ($entity instanceof Agreement)
{
$agreement = $entity;
$repo = $entityManager->getRepository('Gedmo\Loggable\Entity\LogEntry');
$repo->revert($agreement->getTemplate(), $agreement->getTemplateVersion());
}
}
}
行動
このアクションにより、問題なく目的の合意が得られます。
/**
* @Route("/agreement/send/{id}", name="agreement/send")
* @ParamConverter("agreement", class="Bundle:Agreement")
* @Template()
*/
public function sendAction(Request $request, Agreement $agreement) {
*...Code omitted...*
}
このコードを使用すると、例外が発生します (ハードコードされた ID とこのコードはテスト用です)。
/**
* @Route("/agreement/send", name="agreement/send")
* @Template()
*/
public function sendAction(Request $request) {
$em = $this->get('doctrine')->getManager();
$qb = $em->createQueryBuilder()->select('a')->from('AppBundle:Agreement', 'a')->where('a.id=1378');
$agreements = $qb->getQuery()->getResult();
}