0

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();
    }
4

2 に答える 2